Setup

Load packages

rm(list=ls())  # reset workspace
options(scipen=100)  # do not show numbers using exponential

# install & load packages
pacman::p_load(
  openxlsx   # open excel
  , tidyverse
  , magrittr   # extended pipe
  , foreach    # Parallel processing
  , metafor    # meta-analysis
  , MCMCglmm   # comparative analysis
  , orchaRd    # Orchard plot - meta-analysis
  , rotl       # open tree of life
  , ape        # Phylogeny
  , phytools   # Phylogeny
  , knitr  
  , kableExtra # nice tables
  , pander     # nice tables
  , svglite    # Export SVG plots
  , ggiraphExtra # Geom predict
  , ggbeeswarm # Orchard plot
  , ggtree
  , patchwork   # combine multiple plots
  # , R.rsp
)

# Rmarkdown settings
knitr::opts_chunk$set(
  prompt  = FALSE,  # Do not add > or + in inline-code
  message = FALSE, 
  comment = "", 
  warning = FALSE,  # Mute warnings
  tidy    = TRUE
  ) 
options(knitr.kable.NA = '') # Hide NAs in kable table

Custom function

We have custom functions named : get_pred(), get_reg(), get_fixed.MCMCglmm() and get_random.MCMCglmm(), all of which are used later (see below for their functionality) and the code are included here.

#' Title: get_pred
#' function to get prediction intervals (crediblity intervals) from rma objects (metafor)
#'
#' @param model: rma.mv object 
#' @param mod: the name of a moderator 
get_pred <- function(model, mod = " ") {
  I2 <- i2_ml(model) %>%
    as.data.frame() %>%
    rownames_to_column("Partition") %>%
    rename("I2" = ".") %>%
    mutate(percentage = str_c(round(I2*100,1),"%", sep = "")) %>%
    column_to_rownames("Partition")

  name <- as.factor(str_replace(row.names(model$beta), mod, ""))
  len <- length(name)
  
  if (len != 1) {
      newdata <- matrix(NA, ncol = len, nrow = len)
      for (i in 1:len) {
          # getting the position of unique case from X (design matrix)
          pos <- which(model$X[, i] == 1)[[1]]
          newdata[, i] <- model$X[pos, ]
      }
      pred <- predict.rma(model, newmods = newdata)
    } else {
        pred <- predict.rma(model)
    }

    table <- tibble(
      'Dataset' = "",
      'Fixed effects' = name, 
      'Estimate' = model$beta, # regression: estimate
      'LowerCI' = model$ci.lb, # regression: 95ci, 
      'UpperCI'  = model$ci.ub, # regression: 95ci
      'lowerPR' = pred$cr.lb,  # lower prediction range
      'upperPR' = pred$cr.ub, # lower prediction range
      'P'        = model$pval,
    # 'V[species with phylogeny]' =
    #   c(model$sigma2[1], rep("", length(model$beta))),
    # 'V[study]' =
    #   c(model$sigma2[2], rep("", length(model$beta))),
    # 'V[crossed strain]' =
    #   c(model$sigma2[3], rep("", length(model$beta))),
    # 'V[residual]' = 
    #   c(model$sigma2[4], rep("", length(model$beta))),
    'I2[total]' = 
      c(I2["I2_total","percentage"], rep("", length(model$beta)-1)),
    '%I2[species with phylogeny]' = 
      c(I2["I2_spL.name","percentage"], rep("", length(model$beta)-1)),
    '%I2[study]' =
      c(I2["I2_Study.ID","percentage"], rep("", length(model$beta)-1)),
    '%I2[crossed strain]' =
      c(I2["I2_Cross.ID","percentage"], rep("", length(model$beta)-1)),
    '%I2[residual]' = 
      c(I2["I2_ES.ID","percentage"], rep("", length(model$beta)-1)),
    )  %>%
    as.data.frame() %>%
    mutate_at(vars('Estimate':'P'), as.numeric) %>%
    mutate(significance = ifelse(P < 0.05, "*", ""))
}



#' Title: get_reg
#' function to get summary stats from rma objects (metafor)
#' @param model: rma.mv object 
#' @param mod: the name of a moderator 
get_reg <- function(model, mod = " ") {
  
  I2 <- i2_ml(model) %>%
    as.data.frame() %>%
    rownames_to_column("Partition") %>%
    rename("I2" = ".") %>%
    mutate(percentage = str_c(round(I2*100,1),"%", sep = "")) %>%
    column_to_rownames("Partition")
  
  table <- tibble(
    'Dataset' = "",
    'Fixed effects' = c("", row.names(model$beta)),
    'Estimate' = c("", model$beta), # regression: estimate
    'LowerCI' = c("", model$ci.lb), # regression: 95ci, 
    'UpperCI'  = c("", model$ci.ub), # regression: 95ci
    'P'        = c("", model$pval),
    # 'V[species with phylogeny]' =
    #   c(model$sigma2[1], rep("", length(model$beta))),
    # 'V[study]' =
    #   c(model$sigma2[2], rep("", length(model$beta))),
    # 'V[crossed strain]' =
    #   c(model$sigma2[3], rep("", length(model$beta))),
    # 'V[residual]' = 
    #   c(model$sigma2[4], rep("", length(model$beta))),
    'I2[total]' = 
      c(I2["I2_total","percentage"], rep("", length(model$beta))),
    '%I2[species with phylogeny]' = 
      c(I2["I2_spL.name","percentage"], rep("", length(model$beta))),
    '%I2[study]' =
      c(I2["I2_Study.ID","percentage"], rep("", length(model$beta))),
    '%I2[crossed strain]' =
      c(I2["I2_Cross.ID","percentage"], rep("", length(model$beta))),
    '%I2[residual]' = 
      c(I2["I2_ES.ID","percentage"], rep("", length(model$beta))),
    )  %>%
    as.data.frame() %>%
    mutate_at(vars('Estimate':'P'), as.numeric) %>%
    mutate(significance = ifelse(P < 0.05, "*", ""))
}


#' Title: get_random.MCMCglmm
#' 
#' @param x: VCV of MCMCglmm products (i.e. summary('MCMCglmm object'$VCV)), which was transformed if apprecable. 
get_random.MCMCglmm <- function(x) {
  
  bind_cols(
    x$statistics %>%
    as.data.frame,
    x$quantiles %>%
    as.data.frame
    )  %>% 
    rownames_to_column("Random effects")  %>% 
    rename("Estimates" = "Mean") %>%
    as.data.frame %>%
    mutate(
      '95% credible interval' = str_c(
        round(.[,"2.5%"],2), round(.[,"97.5%"],2),
        sep = "--" # en-dash
        )
      ) %>%
    dplyr::select("Random effects", "Estimates", "95% credible interval") 
  
}

#' Title: get_fixed.MCMCglmm
#' 
#' @param x: Solution of MCMCglmm products (i.e. summary('MCMCglmm object'$solutions)), which was transformed if apprecable. 
get_fixed.MCMCglmm <- function(x) {
  
  x %>%
    as.data.frame() %>%
    rownames_to_column(var = "Factors") %>%
    mutate(
      '95% credible interval' = str_c(
        round(.[,"l-95% CI"],2), round(.[,"u-95% CI"],2),
        sep = " -- " # en-dash
        ),
      Estimates = round(post.mean, 2),
      P = round(pMCMC, 3)
      ) %>%
    mutate(significance = ifelse(P < 0.05, "*", "")) %>%
    mutate(
      "Description" = 
        str_c("$\\beta$ = ", Estimates,
              ", CI = ", .[, "95% credible interval"],
              ", P = ", round(P, 3),
              "")
      )

}
  
#++++++++++++++++++++++++++++++++++++++++++++++#
# Setting plot theme for forest plots
#++++++++++++++++++++++++++++++++++++++++++++++#
foresttheme <- theme_bw() +
  theme(
    legend.position = "none",
    axis.line = element_line(size = 0.4, color = "grey50"),
    axis.ticks = element_line(size = 0.3, color = "grey50"),
    axis.text = element_text(size = 9.5, color = "black"),
    panel.grid.major.y = element_blank(),
    panel.grid.minor = element_blank(),
    panel.border = element_blank(),
    strip.text = element_text(size = 9.5, color = "black")
    )

#++++++++++++++++++++++++++++++++++++++++++++++#
# Setting plot theme for forest plots
#++++++++++++++++++++++++++++++++++++++++++++++#
stackedbartheme <- theme(
    strip.text = element_text(size = 13),
    axis.text.y = element_text(size = 13),
    panel.grid.minor = element_blank(),
    panel.grid.major.x = element_blank(),
    axis.ticks.x = element_blank(),
    legend.text = element_text(size = 11),
    legend.background = element_rect("grey95")
  )

#++++++++++++++++++++++++++++++++++++++++++++++#
# Setting plot theme for regression scatterplot
#++++++++++++++++++++++++++++++++++++++++++++++#
regressiontheme <-   theme_bw() +
    theme(
      legend.position = "none",
      axis.ticks = element_line(size = 0.3, color = "grey50"),
      axis.text = element_text(size = 9.5, color = "black"),
      axis.text.y = element_blank(),
      panel.grid.major.y = element_blank(),
      panel.grid.minor = element_blank(),
      panel.border = element_rect(colour = "grey50", size = 0.7),
      strip.text = element_text(size = 9.5, color = "black")
      )

#++++++++++++++++++++++++++++++++++++++++++++++#
# Setting plot theme for orchard plot
#++++++++++++++++++++++++++++++++++++++++++++++#
orchardtheme <-  theme_bw() +
  theme(
    panel.grid.major.y = element_blank(),
    axis.text.y = element_text(size = 14, color = "black", face = "italic"),
    axis.text.x = element_text(size = 14, color = "grey20"),
    axis.title = element_text(size = 14, color = "black"),
    legend.position = c(0.15, 0.002),
    legend.justification = c(0.15, 0.002),
    legend.text = element_text(size = 14),
    legend.title = element_text(size = 14),
    legend.direction = "horizontal"
    )

#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
# Correcting estimate of binomial regression
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
c2 <- (16 * sqrt(3)/(15 * pi))^2

Hypotheses

tibble(
  Factors = c(
    "Genetic divergence",
    "Phenotypic divergence in focal trait",
    "Inviability of reciprocal hybrids (i.e. genetic incompatibility)",
    "Distribution overlap between parental species",
    "Crossing direction (parent-of-origin effect)",
    "Sex-determination system (male heterogamety vs. female heterogamety)",
    "Interaction between crossing direction and sex-determination system",
    "Trait type (sound trait vs. morphology)"
    ),
  'Hypothetical effect for novelty in phenotypic means' = c(
    "Increase. Positively correlate with the genetic divergence at phenotype-determining loci that increase phenotypic novelty through novel allelic interactions (i.e. over/underdominance, dominance, and epistasis) [@Lamkey1999; @Rieseberg1999]",
    "Increase. Indicates the genetic divergence at quantitative trait loci (QTL) that enhances phenotypic novelty [@Lamkey1999]",
    "Reduces trait size by outbreeding depression",
    "Increase. Reinforcement in range overlapping species pairs diverges QTL to develop behavioral isolation, and thus facilitate phenotypic novelty.",
    "Genomic imprinting increases novel phenotype resembles either mother or father (i.e. polar overdominance) [@Cockett1996].",
    "Increase in male heterogamety. In male heterogametic organisms, coadaptation between sex-chromosome and other chromosomes breaks down in F1 males [@Haldane1922; @Schilthuizen2011]. This genetic incompatibility reduce trait size in male heterogametic hybrids.",
    "Male heterogametic organisms tend to exhibit novel phenotype similar to father species, not mother species, due to effect of Y chromosome. Female heterogametic organisms do not show such trend.",
    "Increase in sound because of lower heritability compared to morphology [@Hoffmann2016]"
    ),
  `Hypothetical effect for phenotypic variability` = c(
    "Increase. Increase variation because of increased diversity in novel allelic interactions at phenotype determining loci [@Edmands1999]; increase variation by damaging developmental stability, through genetic incompatibility [@Lerner1954; @Alibert2003].",
    "Increase. Increases diversity in novel allelic interactions at QTL [@Edmands1999]",
    "Reduce. Lethal allelic interactions reduce genetic diversity of surviving hybrids",
    "Reduce. Reinforcement reduces intraspecific variation at QTL, and thus diminish genetic diversity of F1 hybrids at QTL",
    "Not specified",
    "Increase in male heterogamety. Reduced developmental stability increases phenotypic variability of heterogametic F1 males",
    "Not specified",
    "Not specified"
    )
  ) %>% 
  kable("html", caption = "Table S1. Hypotheses for phenotypic novelty and variability of F1 hybrids") %>% 
  kable_styling("striped", position = "left") %>% 
  scroll_box(width = "100%", height = "500px")
Table S1. Hypotheses for phenotypic novelty and variability of F1 hybrids
Factors Hypothetical effect for novelty in phenotypic means Hypothetical effect for phenotypic variability
Genetic divergence Increase. Positively correlate with the genetic divergence at phenotype-determining loci that increase phenotypic novelty through novel allelic interactions (i.e. over/underdominance, dominance, and epistasis) (Lamkey and Edwards 1999; Rieseberg et al. 1999) Increase. Increase variation because of increased diversity in novel allelic interactions at phenotype determining loci (Edmands 1999); increase variation by damaging developmental stability, through genetic incompatibility (Lerner 1954; Alibert and Auffray 2003).
Phenotypic divergence in focal trait Increase. Indicates the genetic divergence at quantitative trait loci (QTL) that enhances phenotypic novelty (Lamkey and Edwards 1999) Increase. Increases diversity in novel allelic interactions at QTL (Edmands 1999)
Inviability of reciprocal hybrids (i.e. genetic incompatibility) Reduces trait size by outbreeding depression Reduce. Lethal allelic interactions reduce genetic diversity of surviving hybrids
Distribution overlap between parental species Increase. Reinforcement in range overlapping species pairs diverges QTL to develop behavioral isolation, and thus facilitate phenotypic novelty. Reduce. Reinforcement reduces intraspecific variation at QTL, and thus diminish genetic diversity of F1 hybrids at QTL
Crossing direction (parent-of-origin effect) Genomic imprinting increases novel phenotype resembles either mother or father (i.e. polar overdominance) (Cockett et al. 1996). Not specified
Sex-determination system (male heterogamety vs. female heterogamety) Increase in male heterogamety. In male heterogametic organisms, coadaptation between sex-chromosome and other chromosomes breaks down in F1 males (Haldane 1922; Schilthuizen et al. 2011). This genetic incompatibility reduce trait size in male heterogametic hybrids. Increase in male heterogamety. Reduced developmental stability increases phenotypic variability of heterogametic F1 males
Interaction between crossing direction and sex-determination system Male heterogametic organisms tend to exhibit novel phenotype similar to father species, not mother species, due to effect of Y chromosome. Female heterogametic organisms do not show such trend. Not specified
Trait type (sound trait vs. morphology) Increase in sound because of lower heritability compared to morphology (Hoffmann et al. 2016) Not specified

Female preference data

tibble(
  Taxon = c(
    "Anura: tree frog (*Hyla*)",
    "Diptera: fruit fly (*Drosophila*)",
    "Orthoptera: bushcricket (*Ephippiger*)",
    "Orthoptera: grasshopper (*Chorthippus*)",
    "Orthoptera: grasshopper (*Chorthippus*)",
    "Orthoptera: grasshopper (*Chorthippus*)",
    "Orthoptera: Hawaiian cricket (*Laupala*)"
    ),
  `Parental species` = c(
    "*H. chrysoscelis* × *H. femoralis*",
    "*D. virilis* female × *D. montana* male",
    "*E. ephippiger* polysyllabic form 
    × *E. ephippiger* monosyllabic form",
    "*C. brunneus* × *C. jacobsi*",
    "*C. biguttulus* × *C. Brunneus*",
    "*C. parallelus* × *C. Montanus*",
    "*L. kohalensis* × *L. Paranigra*"
    ),
  `Reciprocal cross` = c("Viable", "Inviable", rep("Viable", 5)),
  Results = c(
    "**Dominance**. Both reciprocal hybrids preferred hybrids over one parental species but not over the other parental species",
    "**Maternal / paternal inheritance**. Resembled mother in their receptivity, but resembled father in their song requirement",
    "**Additive**. Intermediate mate preferences without a large difference between reciprocal crosses",
    "**Dominance and paternal inheritance**. Both reciprocal hybrids preferred one parental species over themselves. Preference function resembles that of the father",
    "**Additive and dominance**. Several components of preference showed dominance, but other components showed additive inheritance. No maternal/paternal inheritance.",
    "**Novel preference**. Both reciprocal hybrids did not discriminate between males of two parental species",
    "**Additive**. Intermediate preference function, which was similar to reciprocal hybrids, resulting in preference for hybrids"
    ),
  Reference = c(
    "@Doherty1984", "@Isoherranen1999", "@Ritchie2000", "@Bridle2006", 
    "@Gottsberger2019", "@Hochkirch2011", "@Shaw2000"
    )
  ) %>% 
  kable("html", caption = "Table S2. Previously described female mate preference of F1 hybrids") %>% 
  kable_styling("striped", position = "left") %>% 
  scroll_box(width = "100%", height = "500px")
Table S2. Previously described female mate preference of F1 hybrids
Taxon Parental species Reciprocal cross Results Reference
Anura: tree frog (Hyla) H. chrysoscelis × H. femoralis Viable Dominance. Both reciprocal hybrids preferred hybrids over one parental species but not over the other parental species Doherty and Gerhardt (1984)
Diptera: fruit fly (Drosophila) D. virilis female × D. montana male Inviable Maternal / paternal inheritance. Resembled mother in their receptivity, but resembled father in their song requirement Isoherranen et al. (1999)
Orthoptera: bushcricket (Ephippiger) E. ephippiger polysyllabic form × E. ephippiger monosyllabic form Viable Additive. Intermediate mate preferences without a large difference between reciprocal crosses Ritchie (2000)
Orthoptera: grasshopper (Chorthippus) C. brunneus × C. jacobsi Viable Dominance and paternal inheritance. Both reciprocal hybrids preferred one parental species over themselves. Preference function resembles that of the father Bridle et al. (2006)
Orthoptera: grasshopper (Chorthippus) C. biguttulus × C. Brunneus Viable Additive and dominance. Several components of preference showed dominance, but other components showed additive inheritance. No maternal/paternal inheritance. Gottsberger and Mayer (2019)
Orthoptera: grasshopper (Chorthippus) C. parallelus × C. Montanus Viable Novel preference. Both reciprocal hybrids did not discriminate between males of two parental species Hochkirch and Lemke (2011)
Orthoptera: Hawaiian cricket (Laupala) L. kohalensis × L. Paranigra Viable Additive. Intermediate preference function, which was similar to reciprocal hybrids, resulting in preference for hybrids Shaw (2000)

Only 3 out of 7 studies detected additive inheritance in female mate preference during hybridization, showing that non-additivity pervades female mate preference of F1 hybrids. Dominance and parent-of-origin effect (maternal / paternal inheritance) were detected in 3 and 2 studies, respectively. Novel weak preference also appeared in 1 study. Importantly, components of female preference often varied in inheritance mode, indicating that integration of mate preference easily breaks down in F1 hybrids. This summary is based on a non-exhaustive and non-systematic review.

Data description

List of primary studies included

read.xlsx(
  "../data/original.data.xlsx", sheet = "Primary.studies"
  # Same data is also saved as "../data/original.data.Primary.studies.txt"
  ) %>%
  arrange(First.author, Year) %>%
  kable("html") %>% kable_styling("striped", position = "left") %>% 
  scroll_box(width = "100%", height = "500px")
Study.name First.author Year Title Journal
Bentrey&Hoy_1972 Bentley, D. R. 1972 Genetic control of the neuronal network generating cricket (Teleogryllus gryllus) song patterns Animal Behaviour
Blankers.et.al_2015 Blankers, T. 2015 Phenotypic variation and covariation indicate high evolvability of acoustic communication in crickets Journal of Evolutionary Biology
Butlin&Hewitt_1988 Butlin, R. K. 1988 Genetics of behavioural and morphological differences between parapatric subspecies of Chorthippus parallelus (Orthoptera: Acrididae) Biological Journal of the Linnean Society
Carson.et.al_1994 Carson, H. L. 1994 Change in male secondary sexual characters in artificial interspecific hybrid populations Proceedings of the National Academy of Sciences of the United States of America
Coyne_1983 Coyne, J.A. 1983 Genetic basis of differences in genital morphology among three sibling species of Drosophila Evolution
Coyne_1985 Coyne, J.A. 1985 Genetic studies of three sibling species of Drosophila with relationship to theories of speciation Genetical Research
Coyne_1986 Coyne, J.A. 1986 Meiotic segregation and male recombination in interspecific hybrids of Drosophila Genetics
Coyne.et.al_1991 Coyne, J.A. 1991 Genetics of morphological differences and hybrid sterility between Drosophila sechellia and its relatives Genetical Research
Crapon&Fritzsch_1984 Crapon de caprona, MD. 1984 Interspecific fertile hybrids of haplochromine cichlidae (Teleostei) and their possible importance for speciation Netherlands Journal of Zoology
Deregnaucourt_2010 Deregnaucourt, S. 2010 Interspecific hybridization as a tool to understand vocal divergence: The example of crowing in quail (Genus Coturnix) PLoS ONE
Doherty & Gerhardt 1984 Doherty, J. A. 1984 Acoustic communication in hybrid treefrogs: sound production by males and selective phonotaxis by females Journal of Comparative Physiology A
Ewing_1969 Ewing, A.W. 1969 The genetic basis of sound production in Drosophila pseudoobscura and D. persimilis Animal Behaviour
Gadenne et al_1997 Gadenne, C. 1997 Development and pheromone communication systems in hybrids of Agrotis ipsilon and Agrotis segetum (Lepidoptera: Noctuidae) Journal of Chemical Ecology
Gottsberger&Mayer_2007 Gottsberger, B. 2007 Behavioral sterility of hybrid males in acoustically communicating grasshoppers (Acrididae, Gomphocerinae) Journal of Comparative Physiology A: Neuroethology, Sensory, Neural, and Behavioral Physiology
Magalhaes&Seehausen_2010 Magalhaes, I. S. 2010 Genetics of male nuptial colour divergence between sympatric sister species of a Lake Victoria cichlid fish Journal of Evolutionary Biology
Monti et al_2001 Monti, L 2001 Elliptic fourier analysis of the form of genitalia in two Spodoptera species and their hybrids (Lepidoptera: Noctuidae) Biological Journal of the Linnean Society
Musolf et al_2015 Musolf, K 2015 Ultrasonic vocalizations of male mice differ among species and females show assortative preferences for male calls PLoS ONE
Paallysaho et al_2003 Paallysaho, S. 2003 Role of X chromosomal song genes in the evolution of species-specific courtship songs in Drosophila virilis group species Behavior Genetics
Sasabe_et.al_2007 Sasabe, M. 2007 The genetic basis of interspecific differences in genital morphology of closely related carabid beetles Heredity
Shaw_1996 Shaw, K. L. 1996 Polygenic inheritance of a behavioral phenotype: Interspecific genetics of song in the Hawaiian cricket genus Laupala Evolution
Shaw_2000 Shaw, K. L. 2000 Interspecific genetics of mate recognition: Inheritance of female acoustic preference in Hawaiian crickets Evolution
Suvanto et al_1994 Suvanto, L. 1994 Secondary courtship songs and inhibitory songs of Drosophila virilis-group males Behavior Genetics
Tomaru&Oguma_1994 Tomaru, M. 1994 Differences in courtship song in the species of the Drosophila auraria complex Animal Behaviour
van der Sluijs et al_2008 Van Der Sluijs, I. 2008 Female mating preference functions predict sexual selection against hybrids between sibling species of cichlid fish Philosophical Transactions of the Royal Society B: Biological Sciences
Wells_1994 Wells, M. M. 1994 Behavioral responses of hybrid lacewings (Neuroptera: Chrysopidae) to courtship songs Journal of Insect Behavior

Study.name: Including author name(s) and published year

Table of the dataset

Data of phenotype used in this study.

## Phenotype data ##
pheno <- read.xlsx(
    "../data/original.data.xlsx", sheet = "Phenotype"
    # Same data is also saved as "../data/original.data.Phenotype.txt"
    ) %>%
  # Excluding data without any parent data
  drop_na(contains("SD.sp")) %>%
  # to numeric
  mutate_at(
    vars(contains("Mn") | contains("SD") | N.sp1:N.sp2), 
    as.numeric
    ) %>%
  # delete observation with negative mean trait value
  filter(Mn.sp1 > 0 & Mn.sp2 > 0 & homologous == "Yes") %>%   
  # calculate phenotypic difference between parental species
  mutate(
    Pheno.divergence = abs(log(Mn.sp1/Mn.sp2))
    ) %>%
  mutate_at(vars(contains("pheno.div")), scale) %>%
  # describe whether full cross or not
  mutate(
    Reciprocal = ifelse(
      is.na(Mn.hyb12 & Mn.hyb21), 
      "Inviable", "Viable"
      )
    )

# making a scrollable table
kable(pheno, "html") %>% kable_styling("striped", position = "left") %>% 
    scroll_box(width = "100%", height = "500px")
Study.ID Study.name Source Cross.ID Genus sp1.name sp2.name species.pair homologous trait.type trait Mn.sp1 SD.sp1 SE.sp1 Mn.hyb12 SD.hyb12 SE.hyb12 Mn.hyb21 SD.hyb21 SE.hyb21 Mn.sp2 SD.sp2 SE.sp2 Parents.sp1F.sp1 Parents.sp1M.sp1 Parents.sp1F.hyb12 Parents.sp1M.hyb21 Parents.sp2F.hyb21 Parents.sp2M.hyb12 Parents.sp2F.sp2 Parents.sp2M.sp2 N.sp1 N.hyb12 N.hyb21 N.sp2 reps.sp1 reps.hyb12 reps.hyb21 reps.sp2 Pheno.divergence Reciprocal
s001 Blankers.et.al_2015 table1 Gryllus_rubens_Gryllus_texensis Gryllus Gryllus_rubens Gryllus_texensis Gryllus_rubens_Gryllus_texensis Yes sound Carrier frequency 4.7300000 0.2700000 4.8200000 0.2700000 5.0100000 0.1700000 5.1800000 0.2200000 12 12 12 12 73 22 28 44 -0.544841228 Viable
s001 Blankers.et.al_2015 table1 Gryllus_rubens_Gryllus_texensis Gryllus Gryllus_rubens Gryllus_texensis Gryllus_rubens_Gryllus_texensis Yes sound Pulse rate 45.3400000 3.8600000 55.2700000 3.9600000 61.9600000 2.7900000 66.8800000 5.4000000 12 12 12 12 73 22 28 44 -0.086102242 Viable
s001 Blankers.et.al_2015 table1 Gryllus_rubens_Gryllus_texensis Gryllus Gryllus_rubens Gryllus_texensis Gryllus_rubens_Gryllus_texensis Yes sound Pulse duty cycle 0.4300000 0.0600000 0.4600000 0.0800000 0.4800000 0.0800000 0.4400000 0.0800000 12 12 12 12 73 22 28 44 -0.649410595 Viable
s001 Blankers.et.al_2015 table1 Gryllus_rubens_Gryllus_texensis Gryllus Gryllus_rubens Gryllus_texensis Gryllus_rubens_Gryllus_texensis Yes sound Trill rate 0.2800000 0.1500000 0.5900000 0.2500000 0.6800000 0.3500000 1.2800000 0.3900000 12 12 12 12 73 22 28 44 1.656119587 Viable
s001 Blankers.et.al_2015 table1 Gryllus_rubens_Gryllus_texensis Gryllus Gryllus_rubens Gryllus_texensis Gryllus_rubens_Gryllus_texensis Yes sound Trill duty cycle 0.7800000 0.1000000 0.7100000 0.1000000 0.7300000 0.1400000 0.6200000 0.1100000 12 12 12 12 73 22 28 44 -0.331214279 Viable
s002 Butlin&Hewitt_1988 Fig1 parallelus_localityA Chorthippus Chorthippus_parallelus_erythropus Chorthippus_parallelus_parallelus Chorthippus_parallelus_erythropus_Chorthippus_parallelus_parallelus Yes sound EI 14.9600000 3.0958682 12.5000000 1.8973666 11.6000000 2.3216374 9.1888889 1.5863616 10 7 12 9 0.065883205 Viable
s002 Butlin&Hewitt_1988 Fig1 parallelus_localityB Chorthippus Chorthippus_parallelus_erythropus Chorthippus_parallelus_parallelus Chorthippus_parallelus_erythropus_Chorthippus_parallelus_parallelus Yes sound EI 14.9600000 3.0958682 12.7666667 1.7461068 11.7400000 2.9499831 10.7880000 2.4703554 10 3 10 25 -0.181236570 Viable
s002 Butlin&Hewitt_1988 Fig1 parallelus_localityA Chorthippus Chorthippus_parallelus_erythropus Chorthippus_parallelus_parallelus Chorthippus_parallelus_erythropus_Chorthippus_parallelus_parallelus Yes sound SI 15.1375000 11.2491875 0.5000000 9.7000000 6.2282522 11.8750000 6.6447348 8 1 10 6 -0.310936151 Viable
s002 Butlin&Hewitt_1988 Fig1 parallelus_localityB Chorthippus Chorthippus_parallelus_erythropus Chorthippus_parallelus_parallelus Chorthippus_parallelus_erythropus_Chorthippus_parallelus_parallelus Yes sound SI 15.1375000 11.2491875 10.4250000 10.2530483 6.9305556 5.6248059 11.4291667 11.0768873 8 3 9 24 -0.251995019 Viable
s002 Butlin&Hewitt_1988 Fig1 parallelus_localityA Chorthippus Chorthippus_parallelus_erythropus Chorthippus_parallelus_parallelus Chorthippus_parallelus_erythropus_Chorthippus_parallelus_parallelus Yes sound ES 31.6666667 26.6666667 60.7142857 12.9362645 43.6666667 18.5711844 59.4444444 25.4344959 10 7 15 9 0.285206116 Viable
s002 Butlin&Hewitt_1988 Fig1 parallelus_localityB Chorthippus Chorthippus_parallelus_erythropus Chorthippus_parallelus_parallelus Chorthippus_parallelus_erythropus_Chorthippus_parallelus_parallelus Yes sound ES 31.6666667 26.6666667 31.6666667 9.4280904 52.2727273 18.1363067 44.1666667 25.3174292 10 3 11 10 -0.172364334 Viable
s002 Butlin&Hewitt_1988 Fig1 parallelus_localityA Chorthippus Chorthippus_parallelus_erythropus Chorthippus_parallelus_parallelus Chorthippus_parallelus_erythropus_Chorthippus_parallelus_parallelus Yes sound SH 4.1538462 12.6217151 2.3571429 2.8996833 9.2142857 5.3375833 5.9545455 4.6390367 26 14 14 11 -0.130138747 Viable
s002 Butlin&Hewitt_1988 Fig1 parallelus_localityB Chorthippus Chorthippus_parallelus_erythropus Chorthippus_parallelus_parallelus Chorthippus_parallelus_erythropus_Chorthippus_parallelus_parallelus Yes sound SH 4.1538462 12.6217151 4.7857143 5.0345743 7.9166667 5.5295921 7.3666667 5.0793700 26 7 12 30 0.197646553 Viable
s002 Butlin&Hewitt_1988 Fig1 parallelus_localityA Chorthippus Chorthippus_parallelus_erythropus Chorthippus_parallelus_parallelus Chorthippus_parallelus_erythropus_Chorthippus_parallelus_parallelus Yes sound EH 63.0769231 66.4928701 108.5714286 102.7380263 194.2857143 83.6416067 200.0000000 120.3328717 26 14 14 10 1.092591646 Viable
s002 Butlin&Hewitt_1988 Fig1 parallelus_localityB Chorthippus Chorthippus_parallelus_erythropus Chorthippus_parallelus_parallelus Chorthippus_parallelus_erythropus_Chorthippus_parallelus_parallelus Yes sound EH 63.0769231 66.4928701 77.1428571 73.6234213 223.0769231 116.8420772 181.3333333 123.2810700 26 7 13 30 0.941675478 Viable
s002 Butlin&Hewitt_1988 Fig1 parallelus_localityA Chorthippus Chorthippus_parallelus_erythropus Chorthippus_parallelus_parallelus Chorthippus_parallelus_erythropus_Chorthippus_parallelus_parallelus Yes sound COH 4.9800000 5.9337678 7.8571429 6.9755404 6.4285714 5.0350810 2.5000000 3.9080337 25 14 14 11 0.376638926 Viable
s002 Butlin&Hewitt_1988 Fig1 parallelus_localityB Chorthippus Chorthippus_parallelus_erythropus Chorthippus_parallelus_parallelus Chorthippus_parallelus_erythropus_Chorthippus_parallelus_parallelus Yes sound COH 4.9800000 5.9337678 3.5000000 4.8989795 10.1923077 8.6057639 3.7666667 4.6110977 25 8 13 30 -0.254716809 Viable
s002 Butlin&Hewitt_1988 Fig1 parallelus_localityA Chorthippus Chorthippus_parallelus_erythropus Chorthippus_parallelus_parallelus Chorthippus_parallelus_erythropus_Chorthippus_parallelus_parallelus Yes sound COD 60.4615385 13.8153504 51.6000000 7.2000000 58.2857143 17.9181814 44.4000000 11.7575508 13 10 14 5 -0.209234963 Viable
s002 Butlin&Hewitt_1988 Fig1 parallelus_localityB Chorthippus Chorthippus_parallelus_erythropus Chorthippus_parallelus_parallelus Chorthippus_parallelus_erythropus_Chorthippus_parallelus_parallelus Yes sound COD 60.4615385 13.8153504 66.0000000 9.7979590 55.0909091 11.9503103 43.5000000 14.6201915 13 3 11 16 -0.177692520 Viable
s002 Butlin&Hewitt_1988 Fig1 parallelus_localityA Chorthippus Chorthippus_parallelus_erythropus Chorthippus_parallelus_parallelus Chorthippus_parallelus_erythropus_Chorthippus_parallelus_parallelus Yes sound EL 3.0400000 0.4983974 3.1857143 0.4517540 2.8076923 0.4269058 2.2250000 0.2633913 10 7 13 8 -0.204101811 Viable
s002 Butlin&Hewitt_1988 Fig1 parallelus_localityB Chorthippus Chorthippus_parallelus_erythropus Chorthippus_parallelus_parallelus Chorthippus_parallelus_erythropus_Chorthippus_parallelus_parallelus Yes sound EL 3.0400000 0.4983974 2.6333333 0.1885618 2.9181818 0.3242283 2.1416667 0.5626697 10 3 11 24 -0.145305786 Viable
s002 Butlin&Hewitt_1988 Fig1 parallelus_localityA Chorthippus Chorthippus_parallelus_erythropus Chorthippus_parallelus_parallelus Chorthippus_parallelus_erythropus_Chorthippus_parallelus_parallelus Yes sound NS 13.9000000 2.6153394 15.6666667 2.0344259 13.8846154 1.6426274 12.0000000 1.5000000 10 6 13 10 -0.458428548 Viable
s002 Butlin&Hewitt_1988 Fig1 parallelus_localityB Chorthippus Chorthippus_parallelus_erythropus Chorthippus_parallelus_parallelus Chorthippus_parallelus_erythropus_Chorthippus_parallelus_parallelus Yes sound NS 13.9000000 2.6153394 12.1666667 0.4714045 13.6818182 1.1922615 12.7000000 2.4819347 10 3 11 25 -0.545754618 Viable
s002 Butlin&Hewitt_1988 Fig1 parallelus_localityA Chorthippus Chorthippus_parallelus_erythropus Chorthippus_parallelus_parallelus Chorthippus_parallelus_erythropus_Chorthippus_parallelus_parallelus Yes sound SL 0.2270000 0.0124900 0.2121429 0.0174964 0.2065385 0.0274131 0.1987500 0.0264280 10 7 13 8 -0.480115420 Viable
s002 Butlin&Hewitt_1988 Fig1 parallelus_localityB Chorthippus Chorthippus_parallelus_erythropus Chorthippus_parallelus_parallelus Chorthippus_parallelus_erythropus_Chorthippus_parallelus_parallelus Yes sound SL 0.2270000 0.0124900 0.2183333 0.0205480 0.2168182 0.0224897 0.1750000 0.0284376 10 3 11 23 -0.284098069 Viable
s002 Butlin&Hewitt_1988 Fig1 parallelus_localityA Chorthippus Chorthippus_parallelus_erythropus Chorthippus_parallelus_parallelus Chorthippus_parallelus_erythropus_Chorthippus_parallelus_parallelus Yes sound COR 3.5000000 3.2730000 3.3181818 3.1298943 3.2500000 3.0741110 2.5000000 2.4074367 14 11 12 4 -0.166562938 Viable
s002 Butlin&Hewitt_1988 Fig1 parallelus_localityB Chorthippus Chorthippus_parallelus_erythropus Chorthippus_parallelus_parallelus Chorthippus_parallelus_erythropus_Chorthippus_parallelus_parallelus Yes sound COR 3.5000000 3.2730000 3.0000000 2.8262465 2.5000000 2.3614732 1.6333333 1.4974284 14 2 11 15 0.489079925 Viable
s002 Butlin&Hewitt_1988 Fig1 parallelus_localityA Chorthippus Chorthippus_parallelus_erythropus Chorthippus_parallelus_parallelus Chorthippus_parallelus_erythropus_Chorthippus_parallelus_parallelus Yes morphology RL 4.0142857 0.2799417 3.7545455 0.1724879 3.7428571 0.1545236 3.5571429 0.3499271 21 11 14 7 -0.498599402 Viable
s002 Butlin&Hewitt_1988 Fig1 parallelus_localityB Chorthippus Chorthippus_parallelus_erythropus Chorthippus_parallelus_parallelus Chorthippus_parallelus_erythropus_Chorthippus_parallelus_parallelus Yes morphology RL 4.0142857 0.2799417 3.9111111 0.1940472 3.7000000 0.2449490 3.4481481 0.2283116 21 18 16 27 -0.450665719 Viable
s002 Butlin&Hewitt_1988 Fig1 parallelus_localityA Chorthippus Chorthippus_parallelus_erythropus Chorthippus_parallelus_parallelus Chorthippus_parallelus_erythropus_Chorthippus_parallelus_parallelus Yes morphology NP 146.4285714 14.2380156 133.3333333 10.6718737 119.2857143 9.0350790 112.1428571 10.3015751 21 12 14 27 -0.273932094 Viable
s002 Butlin&Hewitt_1988 Fig1 parallelus_localityB Chorthippus Chorthippus_parallelus_erythropus Chorthippus_parallelus_parallelus Chorthippus_parallelus_erythropus_Chorthippus_parallelus_parallelus Yes morphology NP 146.4285714 14.2380156 126.5000000 9.6306801 106.2500000 17.9843682 94.2592593 11.1971974 21 20 16 7 -0.006349655 Viable
s002 Butlin&Hewitt_1988 Fig1 parallelus_localityA Chorthippus Chorthippus_parallelus_erythropus Chorthippus_parallelus_parallelus Chorthippus_parallelus_erythropus_Chorthippus_parallelus_parallelus Yes morphology PD 36.5294118 3.1081988 34.3333333 2.1081851 31.3636364 2.2268089 30.2000000 3.9191836 17 9 11 5 -0.391744730 Viable
s002 Butlin&Hewitt_1988 Fig1 parallelus_localityB Chorthippus Chorthippus_parallelus_erythropus Chorthippus_parallelus_parallelus Chorthippus_parallelus_erythropus_Chorthippus_parallelus_parallelus Yes morphology PD 36.5294118 3.1081988 32.5294118 2.1176471 29.3333333 3.5433819 27.2222222 1.8724777 17 17 12 18 -0.231852056 Viable
s003 Carson.et.al_1994 table4 Drosophila_heteroneura_Drosophila_silvestris Drosophila Drosophila_heteroneura Drosophila_silvestris Drosophila_heteroneura_Drosophila_silvestris Yes morphology Number of tibial cilia on male foreleg 37.2500000 1.6500000 45.1500000 2.7600000 59.5700000 3.6700000 72.8500000 6.3300000 35 35 35 35 35 35 35 35 20 20 20 20 0.348315583 Viable
s004 Coyne_1983 table3 BGxMutant Drosophila Drosophila_mauritiana Drosophila_simulans Drosophila_mauritiana_Drosophila_simulans Yes morphology GA 1442.0000000 202.6573463 37.000 5141.0000000 506.6665570 91.000 12166.0000000 735.0000000 147.0000 3 3 20 20 20 20 3 3 30 0 31 25 2.599978426 Inviable
s004 Coyne_1983 table3 BGxMutant Drosophila Drosophila_mauritiana Drosophila_simulans Drosophila_mauritiana_Drosophila_simulans Yes morphology WL 462.0000000 10.9544512 2.000 487.0000000 11.1355287 2.000 477.0000000 10.0000000 2.0000 3 3 20 20 20 20 3 3 30 0 31 25 -0.635606580 Inviable
s004 Coyne_1983 table3 BGxMutant Drosophila Drosophila_mauritiana Drosophila_simulans Drosophila_mauritiana_Drosophila_simulans Yes morphology GA/WL 3.1200000 0.4381780 0.080 10.5800000 2.0600728 0.370 25.4900000 1.5000000 0.3000 3 3 20 20 20 20 3 3 30 0 31 25 2.550441963 Inviable
s004 Coyne_1983 table3 BGxSPD(wildtype) Drosophila Drosophila_mauritiana Drosophila_simulans Drosophila_mauritiana_Drosophila_simulans Yes morphology GA 1442.0000000 202.6573463 37.000 5139.0000000 471.0413995 86.000 5400.0000000 651.7898434 119.000 12050.0000000 1007.8095058 184.0000 3 3 20 20 20 20 3 3 30 30 30 30 2.585221856 Viable
s004 Coyne_1983 table3 BGxSPD(wildtype) Drosophila Drosophila_mauritiana Drosophila_simulans Drosophila_mauritiana_Drosophila_simulans Yes morphology WL 462.0000000 10.9544512 2.000 497.0000000 10.9544512 2.000 487.0000000 10.9544512 2.000 1263.0000000 27.3861279 5.0000 3 3 20 20 20 20 3 3 30 30 30 30 0.864197270 Viable
s004 Coyne_1983 table3 BGxSPD(wildtype) Drosophila Drosophila_mauritiana Drosophila_simulans Drosophila_mauritiana_Drosophila_simulans Yes morphology GA/WL 3.1200000 0.4381780 0.080 10.3500000 0.9859006 0.180 11.0900000 1.2597619 0.230 9.5380000 0.7558571 0.1380 3 3 20 20 20 20 3 3 30 30 30 30 1.036354019 Viable
s005 Coyne_1985 table1&2 BGxOxnard Drosophila Drosophila_mauritiana Drosophila_simulans Drosophila_mauritiana_Drosophila_simulans Yes morphology Sex comb tooth number 14.3100000 1.1313708 0.080 12.3300000 1.0148892 0.100 12.1000000 0.9899495 0.070 9.8600000 0.8485281 0.0600 200 103 200 200 -0.111112971 Viable
s006 Coyne_1986 table1 FC Drosophila Drosophila_sechellia Drosophila_simulans Drosophila_sechellia_Drosophila_simulans Yes morphology 6T 176.0000000 44.5477272 10.500 142.0000000 36.9109740 8.700 15.7000000 2.6153394 0.6000 8 8 18 18 19 3.037736912 Inviable
s006 Coyne_1986 table1 FC Drosophila Drosophila_sechellia Drosophila_simulans Drosophila_sechellia_Drosophila_simulans Yes morphology 7T 49.3000000 12.3036580 2.900 393.9000000 97.5807358 23.000 335.2000000 61.0245852 14.0000 8 8 18 18 19 2.267571704 Inviable
s006 Coyne_1986 table1 FC Drosophila Drosophila_sechellia Drosophila_simulans Drosophila_sechellia_Drosophila_simulans Yes morphology 6Tratio 0.7790000 0.0169706 0.004 0.2640000 0.0169706 0.004 0.0490000 0.0305123 0.0070 8 8 18 18 19 3.575856725 Inviable
s006 Coyne_1986 table1 f^2 Drosophila Drosophila_sechellia Drosophila_simulans Drosophila_sechellia_Drosophila_simulans Yes morphology 6T 176.0000000 44.5477272 10.500 142.7000000 11.1323852 2.700 17.9000000 6.1846584 1.5000 8 8 18 17 17 2.835746058 Inviable
s006 Coyne_1986 table1 f^2 Drosophila Drosophila_sechellia Drosophila_simulans Drosophila_sechellia_Drosophila_simulans Yes morphology 7T 49.3000000 12.3036580 2.900 459.0000000 53.6003731 13.000 424.2000000 78.3390069 19.0000 8 8 18 17 17 2.630270622 Inviable
s006 Coyne_1986 table1 f^2 Drosophila Drosophila_sechellia Drosophila_simulans Drosophila_sechellia_Drosophila_simulans Yes morphology 6Tratio 0.7790000 0.0169706 0.004 0.2380000 0.0164924 0.004 0.0400000 0.0123693 0.0030 8 8 18 17 17 3.888440179 Inviable
s006 Coyne_1986 table1 RMdet Drosophila Drosophila_sechellia Drosophila_simulans Drosophila_sechellia_Drosophila_simulans Yes morphology 6T 176.0000000 44.5477272 10.500 142.8000000 35.0000000 7.000 26.9000000 10.0697567 2.6000 8 8 18 25 15 2.208355177 Inviable
s006 Coyne_1986 table1 RMdet Drosophila Drosophila_sechellia Drosophila_simulans Drosophila_sechellia_Drosophila_simulans Yes morphology 7T 49.3000000 12.3036580 2.900 385.2000000 67.5000000 13.500 541.9000000 199.0713440 51.4000 8 8 18 25 15 3.007446168 Inviable
s006 Coyne_1986 table1 RMdet Drosophila Drosophila_sechellia Drosophila_simulans Drosophila_sechellia_Drosophila_simulans Yes morphology 6Tratio 0.7790000 0.0169706 0.004 0.2690000 0.0350000 0.007 0.0480000 0.0034857 0.0009 8 8 18 25 15 3.607615970 Inviable
s006 Coyne_1986 table1 RM Drosophila Drosophila_sechellia Drosophila_simulans Drosophila_sechellia_Drosophila_simulans Yes morphology 6T 176.0000000 44.5477272 10.500 184.2000000 50.0000000 10.000 25.0000000 5.4221767 1.4000 8 8 18 25 15 2.321180579 Inviable
s006 Coyne_1986 table1 RM Drosophila Drosophila_sechellia Drosophila_simulans Drosophila_sechellia_Drosophila_simulans Yes morphology 7T 49.3000000 12.3036580 2.900 381.7000000 73.0000000 14.600 612.6000000 115.4149037 29.8000 8 8 18 25 15 3.196330430 Inviable
s006 Coyne_1986 table1 RM Drosophila Drosophila_sechellia Drosophila_simulans Drosophila_sechellia_Drosophila_simulans Yes morphology 6Tratio 0.7790000 0.0169706 0.004 0.3220000 0.0400000 0.008 0.0390000 0.0023238 0.0006 8 8 18 25 15 3.927436409 Inviable
s008 Coyne.et.al_1991 table4 pn_j_irX85 Drosophila Drosophila_mauritiana Drosophila_sechellia Drosophila_mauritiana_Drosophila_sechellia Yes morphology Genital area 1.7460000 0.2100000 0.035 3.3230000 0.4501244 0.074 3.1040000 0.3710485 0.061 5.3110000 0.5231176 0.0860 36 37 37 37 1.028655549 Viable
s008 Coyne.et.al_1991 table4 pn_j_irX85 Drosophila Drosophila_mauritiana Drosophila_sechellia Drosophila_mauritiana_Drosophila_sechellia Yes morphology Tibia length 0.4410000 0.0120000 0.002 0.4740000 0.0121655 0.002 0.4870000 0.0182483 0.003 0.4690000 0.0182483 0.0030 36 37 37 37 -0.590004930 Viable
s009 Crapon&Fritzsch_1984 table4 Haplochromis_burtoni_Haplochromis_nubilus Haplochromis Haplochromis_burtoni Haplochromis_nubilus Haplochromis_burtoni_Haplochromis_nubilus Yes morphology egg dummy size 8.9000000 0.7000000 10.0000000 1.6000000 8.3000000 0.8000000 48 34 58 -0.577316397 Inviable
s009 Crapon&Fritzsch_1984 table4 Haplochromis_burtoni_Haplochromis_nubilus Haplochromis Haplochromis_burtoni Haplochromis_nubilus Haplochromis_burtoni_Haplochromis_nubilus Yes morphology egg dummy number 6.7000000 1.8000000 4.3000000 1.0000000 2.5000000 0.6000000 48 34 58 0.833602237 Inviable
s009 Crapon&Fritzsch_1984 table4 Haplochromis_burtoni_Haplochromis_nubilus Haplochromis Haplochromis_burtoni Haplochromis_nubilus Haplochromis_burtoni_Haplochromis_nubilus Yes morphology egg dummy position 1.4000000 0.6000000 3.9000000 1.2000000 5.4000000 0.6000000 48 34 58 1.394429398 Inviable
s010 Deregnaucourt_2010 table2 Coturnix_coturnix_coturnix_Coturnix_japonica Coturnix Coturnix_coturnix_coturnix Coturnix_japonica Coturnix_coturnix_coturnix_Coturnix_japonica Yes sound S2 172.0000000 86.6833317 17.000 168.0000000 59.2368129 11.000 182.0000000 54.7448628 9.000 59.0000000 79.3725393 15.0000 8 8 15 15 26 29 37 28 0.963200823 Viable
s11 Doherty & Gerhardt 1984 fig4 Hyla_chrysoscelis_Hyla_femoralis Hyla Hyla_chrysoscelis Hyla_femoralis Hyla_chrysoscelis_Hyla_femoralis Yes sound pulse/call 29.3023256 3.2558140 15.3488372 4.1860465 20.0000000 9.3023256 4.2420000 0.6225769 5 5 4 5 2.291952220 Viable
s11 Doherty & Gerhardt 1984 fig4 Hyla_chrysoscelis_Hyla_femoralis Hyla Hyla_chrysoscelis Hyla_femoralis Hyla_chrysoscelis_Hyla_femoralis Yes sound pulse duration 15.3191489 1.2765957 17.0212766 8.5106383 17.8723404 7.2340426 48.5106383 7.2340426 6 6 5 5 1.090615675 Viable
s11 Doherty & Gerhardt 1984 fig4 Hyla_chrysoscelis_Hyla_femoralis Hyla Hyla_chrysoscelis Hyla_femoralis Hyla_chrysoscelis_Hyla_femoralis Yes sound pulse rise 7.6068376 1.1965812 2.3931624 1.8803419 1.9658120 1.1965812 1.3675214 0.4273504 6 6 5 5 1.958354051 Viable
s11 Doherty & Gerhardt 1984 fig4 Hyla_chrysoscelis_Hyla_femoralis Hyla Hyla_chrysoscelis Hyla_femoralis Hyla_chrysoscelis_Hyla_femoralis Yes sound pulse decay 7.7142857 2.0571429 10.2857143 4.8857143 8.4000000 3.2571429 4.8000000 1.7142857 6 5 5 5 0.045972199 Viable
s11 Doherty & Gerhardt 1984 fig4 Hyla_chrysoscelis_Hyla_femoralis Hyla Hyla_chrysoscelis Hyla_femoralis Hyla_chrysoscelis_Hyla_femoralis Yes sound pulse period 26.6304348 5.9782609 78.2608696 23.9130435 80.4347826 15.7608696 157.6086957 60.3260870 5 5 5 5 2.053870707 Viable
s12 Ewing_1969 table2 Drosophila_persimilis_Drosophila_pseudoobscura Drosophila Drosophila_persimilis Drosophila_pseudoobscura Drosophila_persimilis_Drosophila_pseudoobscura Yes sound Mean HRR song pulse intervals in msec 66.8000000 10.9000000 48.7000000 7.9000000 56.8000000 7.3000000 42.6000000 4.8000000 25 25 25 25 4 4 4 4 386 273 268 281 0.008067489 Viable
s13 van der Sluijs et al_2008 table1 Pundamilia_nyererei_Pundamilia_pundamilia Pundamilia Pundamilia_nyererei Pundamilia_pundamilia Pundamilia_nyererei_Pundamilia_pundamilia Yes morphology colour score 3.8900000 0.2121320 0.050 2.2100000 0.8668333 0.170 2.2500000 0.8049845 0.180 0.2100000 0.3487119 0.0800 18 26 20 19 3.811311702 Viable
s13 van der Sluijs et al_2008 table1 Pundamilia_nyererei_Pundamilia_pundamilia Pundamilia Pundamilia_nyererei Pundamilia_pundamilia Pundamilia_nyererei_Pundamilia_pundamilia Yes morphology n bars 6.3600000 0.4666905 0.110 5.3500000 0.8668333 0.170 5.9500000 0.4919350 0.110 5.1100000 0.6538348 0.1500 18 26 20 19 -0.347765189 Viable
s14 Gadenne et al_1997 table1 Agrotis_ipsilon_Agrotis_segetum Agrotis Agrotis_ipsilon Agrotis_segetum Agrotis_ipsilon_Agrotis_segetum Yes morphology Harp_h1 328.2000000 29.9000000 440.5000000 35.3000000 611.5000000 79.6000000 >100 >100 4 4 0 0 >100 >100 30 24 0 25 0.273675987 Inviable
s14 Gadenne et al_1997 table1 Agrotis_ipsilon_Agrotis_segetum Agrotis Agrotis_ipsilon Agrotis_segetum Agrotis_ipsilon_Agrotis_segetum Yes morphology Harp_h2 1029.7000000 41.5000000 861.4000000 40.4000000 750.3000000 44.8000000 >100 >100 4 4 0 0 >100 >100 30 24 0 25 -0.197249077 Inviable
s14 Gadenne et al_1997 table1 Agrotis_ipsilon_Agrotis_segetum Agrotis Agrotis_ipsilon Agrotis_segetum Agrotis_ipsilon_Agrotis_segetum Yes morphology Harp_h1/h2 0.3200000 0.0300000 0.5100000 0.0300000 0.8000000 0.1000000 >100 >100 4 4 0 0 >100 >100 30 24 0 25 0.726513411 Inviable
s14 Gadenne et al_1997 table1 Agrotis_ipsilon_Agrotis_segetum Agrotis Agrotis_ipsilon Agrotis_segetum Agrotis_ipsilon_Agrotis_segetum Yes morphology Valva_v1 608.0000000 44.5000000 672.7000000 70.0000000 732.2000000 73.9000000 >100 >100 4 4 0 0 >100 >100 30 24 0 25 -0.398517284 Inviable
s14 Gadenne et al_1997 table1 Agrotis_ipsilon_Agrotis_segetum Agrotis Agrotis_ipsilon Agrotis_segetum Agrotis_ipsilon_Agrotis_segetum Yes morphology Valva_v2 891.1000000 69.6000000 817.7000000 74.0000000 818.0000000 84.8000000 >100 >100 4 4 0 0 >100 >100 30 24 0 25 -0.552982374 Inviable
s14 Gadenne et al_1997 table1 Agrotis_ipsilon_Agrotis_segetum Agrotis Agrotis_ipsilon Agrotis_segetum Agrotis_ipsilon_Agrotis_segetum Yes morphology Valva_v1/v2 0.6800000 0.0400000 0.8200000 0.0800000 0.9000000 0.0700000 >100 >100 4 4 0 0 >100 >100 30 24 0 25 -0.253080256 Inviable
s14 Gadenne et al_1997 table1 Agrotis_ipsilon_Agrotis_segetum Agrotis Agrotis_ipsilon Agrotis_segetum Agrotis_ipsilon_Agrotis_segetum Yes morphology Valva_v3 3696.4000000 134.5000000 3387.1000000 125.0000000 3314.2000000 143.4000000 >100 >100 4 4 0 0 >100 >100 30 24 0 25 -0.516710910 Inviable
s14 Gadenne et al_1997 table1 Agrotis_ipsilon_Agrotis_segetum Agrotis Agrotis_ipsilon Agrotis_segetum Agrotis_ipsilon_Agrotis_segetum Yes morphology Clasper surface 269.6000000 12.4000000 317.4000000 17.5000000 415.9000000 31.4000000 >100 >100 4 4 0 0 >100 >100 30 24 0 25 -0.017105678 Inviable
s14 Gadenne et al_1997 table1 Agrotis_ipsilon_Agrotis_segetum Agrotis Agrotis_ipsilon Agrotis_segetum Agrotis_ipsilon_Agrotis_segetum Yes morphology Juxta_j1 437.0000000 33.8000000 329.8000000 20.5000000 281.1000000 25.2000000 >100 >100 4 4 0 0 >100 >100 30 24 0 25 -0.005219039 Inviable
s14 Gadenne et al_1997 table1 Agrotis_ipsilon_Agrotis_segetum Agrotis Agrotis_ipsilon Agrotis_segetum Agrotis_ipsilon_Agrotis_segetum Yes morphology Juxta_j2 164.0000000 24.0000000 194.7000000 23.8000000 234.6000000 21.2000000 >100 >100 4 4 0 0 >100 >100 30 24 0 25 -0.133380509 Inviable
s14 Gadenne et al_1997 table1 Agrotis_ipsilon_Agrotis_segetum Agrotis Agrotis_ipsilon Agrotis_segetum Agrotis_ipsilon_Agrotis_segetum Yes morphology Juxta_j1/j2 0.3800000 0.0700000 0.5900000 0.0900000 0.8400000 0.1100000 >100 >100 4 4 0 0 >100 >100 30 24 0 25 0.536967787 Inviable
s14 Gadenne et al_1997 table1 Agrotis_ipsilon_Agrotis_segetum Agrotis Agrotis_ipsilon Agrotis_segetum Agrotis_ipsilon_Agrotis_segetum Yes morphology Vesica teeth 17.0000000 3.2000000 27.6000000 5.8000000 40.5000000 5.1000000 >100 >100 4 4 0 0 >100 >100 30 24 0 25 0.652269216 Inviable
s15 Gottsberger&Mayer_2007 table1 Chorthippus_biguttulus_Chorthippus_brunneus Chorthippus Chorthippus_biguttulus Chorthippus_brunneus Chorthippus_biguttulus_Chorthippus_brunneus Yes sound Song duration 11.8400000 3.7000000 8.3400000 3.4500000 12.5400000 3.3700000 12.2600000 4.8200000 6 6 3 3 35 19 18 22 -0.631129479 Viable
s15 Gottsberger&Mayer_2007 table1 Chorthippus_biguttulus_Chorthippus_brunneus Chorthippus Chorthippus_biguttulus Chorthippus_brunneus Chorthippus_biguttulus_Chorthippus_brunneus Yes sound Phrase duration 2.0700000 0.3200000 0.4500000 0.0600000 0.5600000 0.1500000 0.1800000 0.0400000 6 6 3 3 35 19 18 22 3.077050352 Viable
s15 Gottsberger&Mayer_2007 table1 Chorthippus_biguttulus_Chorthippus_brunneus Chorthippus Chorthippus_biguttulus Chorthippus_brunneus Chorthippus_biguttulus_Chorthippus_brunneus Yes sound Phrase pause 2.0600000 0.5700000 1.7400000 0.4500000 1.9400000 0.3900000 1.6600000 0.5400000 6 6 3 3 35 19 18 22 -0.352294492 Viable
s15 Gottsberger&Mayer_2007 table1 Chorthippus_biguttulus_Chorthippus_brunneus Chorthippus Chorthippus_biguttulus Chorthippus_brunneus Chorthippus_biguttulus_Chorthippus_brunneus Yes sound Number of phrases 3.2000000 0.9000000 4.7000000 1.7000000 5.9000000 1.6000000 7.8000000 2.4000000 6 6 3 3 35 19 18 22 0.687517181 Viable
s15 Gottsberger&Mayer_2007 table1 Chorthippus_biguttulus_Chorthippus_brunneus Chorthippus Chorthippus_biguttulus Chorthippus_brunneus Chorthippus_biguttulus_Chorthippus_brunneus Yes sound Syllables per phrase 32.5000000 6.9000000 3.4000000 1.8000000 2.0000000 0.7000000 5.3000000 1.0000000 6 6 3 3 35 19 18 22 2.108508114 Viable
s15 Gottsberger&Mayer_2007 table1 Chorthippus_biguttulus_Chorthippus_brunneus Chorthippus Chorthippus_biguttulus Chorthippus_brunneus Chorthippus_biguttulus_Chorthippus_brunneus Yes sound Pulses per syllable 6.2000000 0.5000000 20.2000000 16.9000000 32.0000000 10.5000000 3.1000000 0.1000000 6 6 3 3 35 19 18 22 0.382812357 Viable
s15 Gottsberger&Mayer_2007 table1 Chorthippus_biguttulus_Chorthippus_brunneus Chorthippus Chorthippus_biguttulus Chorthippus_brunneus Chorthippus_biguttulus_Chorthippus_brunneus Yes sound Syllable period 60.1000000 7.0000000 193.8000000 156.7000000 257.7000000 106.8000000 29.6000000 4.5000000 6 6 3 3 35 19 18 22 0.406052394 Viable
s15 Gottsberger&Mayer_2007 table1 Chorthippus_biguttulus_Chorthippus_brunneus Chorthippus Chorthippus_biguttulus Chorthippus_brunneus Chorthippus_biguttulus_Chorthippus_brunneus Yes sound Pulse period 8.6000000 1.2000000 7.9000000 0.4000000 8.0000000 0.5000000 8.8000000 1.4000000 6 6 3 3 35 19 18 22 -0.649410595 Viable
s15 Gottsberger&Mayer_2007 table1 Chorthippus_biguttulus_Chorthippus_brunneus Chorthippus Chorthippus_biguttulus Chorthippus_brunneus Chorthippus_biguttulus_Chorthippus_brunneus Yes sound Phase-shift in 85.9000000 15.2000000 159.6000000 28.0000000 165.0000000 24.4000000 131.9000000 15.6000000 6 6 3 3 35 19 18 22 -0.024260592 Viable
s16 Bentrey&Hoy_1972 table1 Teleogryllus_commodus_Teleogryllus_oceanicus Teleogryllus Teleogryllus_commodus Teleogryllus_oceanicus Teleogryllus_commodus_Teleogryllus_oceanicus Yes sound Intra-chirp interval 52.1000000 6.8000000 60.4000000 6.1000000 57.5000000 6.5000000 66.8000000 6.7000000 12 12 12 12 12 12 12 12 5 10 10 5 489 807 712 290 -0.302005098 Viable
s16 Bentrey&Hoy_1972 table1 Teleogryllus_commodus_Teleogryllus_oceanicus Teleogryllus Teleogryllus_commodus Teleogryllus_oceanicus Teleogryllus_commodus_Teleogryllus_oceanicus Yes sound Intra-trill interval 31.7000000 3.5000000 36.7000000 5.0000000 33.0000000 3.8000000 41.0000000 1.8000000 12 12 12 12 12 12 12 12 5 10 10 5 1840 2450 2833 740 -0.288578184 Viable
s16 Bentrey&Hoy_1972 table1 Teleogryllus_commodus_Teleogryllus_oceanicus Teleogryllus Teleogryllus_commodus Teleogryllus_oceanicus Teleogryllus_commodus_Teleogryllus_oceanicus Yes sound Inter-trill interval 160.9000000 50.6000000 154.0000000 38.8000000 136.9000000 23.6000000 122.8000000 14.1000000 12 12 12 12 12 12 12 12 5 10 10 5 119 693 857 813 -0.268599892 Viable
s16 Bentrey&Hoy_1972 table1 Teleogryllus_commodus_Teleogryllus_oceanicus Teleogryllus Teleogryllus_commodus Teleogryllus_oceanicus Teleogryllus_commodus_Teleogryllus_oceanicus Yes sound No. of A-pulses per chirp 5.9000000 0.9000000 4.9000000 0.7000000 4.2000000 0.6000000 4.8000000 0.9000000 12 12 12 12 12 12 12 12 5 10 10 5 100 100 100 100 -0.367007059 Viable
s16 Bentrey&Hoy_1972 table1 Teleogryllus_commodus_Teleogryllus_oceanicus Teleogryllus Teleogryllus_commodus Teleogryllus_oceanicus Teleogryllus_commodus_Teleogryllus_oceanicus Yes sound No. of B-pulses per trill 10.7000000 5.3000000 4.9000000 2.0000000 4.5000000 1.5000000 2.0000000 0.1000000 12 12 12 12 12 12 12 12 5 10 10 5 147 200 194 250 1.898358907 Viable
s16 Bentrey&Hoy_1972 table1 Teleogryllus_commodus_Teleogryllus_oceanicus Teleogryllus Teleogryllus_commodus Teleogryllus_oceanicus Teleogryllus_commodus_Teleogryllus_oceanicus Yes sound No. of B-pulses per phrase 21.5000000 10.4000000 19.4000000 4.7000000 18.4000000 4.9000000 20.9000000 3.0000000 12 12 12 12 12 12 12 12 5 10 10 5 34 37 28 38 -0.641225209 Viable
s16 Bentrey&Hoy_1972 table1 Teleogryllus_commodus_Teleogryllus_oceanicus Teleogryllus Teleogryllus_commodus Teleogryllus_oceanicus Teleogryllus_commodus_Teleogryllus_oceanicus Yes sound No. of trills per phrase 2.3000000 1.2000000 4.8000000 1.2000000 4.2000000 1.0000000 9.4000000 2.3000000 12 12 12 12 12 12 12 12 5 10 10 5 100 100 100 100 1.483570683 Viable
s16 Bentrey&Hoy_1972 table1 Teleogryllus_commodus_Teleogryllus_oceanicus Teleogryllus Teleogryllus_commodus Teleogryllus_oceanicus Teleogryllus_commodus_Teleogryllus_oceanicus Yes sound Phrase repetition rate 41.7000000 18.1000000 33.0000000 7.0000000 37.5000000 5.3000000 28.5000000 2.4000000 12 12 12 12 12 12 12 12 5 10 10 5 102 70 105 77 -0.098598877 Viable
s16 Bentrey&Hoy_1972 table2 Gryllus_armatus_Gryllus_rubens Gryllus Gryllus_armatus Gryllus_rubens Gryllus_armatus_Gryllus_rubens Yes sound IPI 14.6000000 1.7000000 17.4000000 2.0000000 19.8000000 3.6000000 12 12 12 12 12 12 12 12 5 5 5 785 837 439 -0.215561704 Inviable
s16 Bentrey&Hoy_1972 table3 Gryllus_armatus_Gryllus_rubens Gryllus Gryllus_armatus Gryllus_rubens Gryllus_armatus_Gryllus_rubens Yes sound Chirp length 3.0095000 0.4045488 3.0256500 1.1668687 120.8835000 98.8883015 4 6 5 1016 2275 1027 5.003474245 Inviable
s16 Bentrey&Hoy_1972 table3 Gryllus_campestris_Gryllus_rubens Gryllus Gryllus_campestris Gryllus_rubens Gryllus_campestris_Gryllus_rubens Yes sound Chirp length 6.4650000 0.3482456 16.1350000 11.5580827 120.8835000 98.8883015 4 1 5 1007 206 1027 3.825739945 Inviable
s17 Magalhaes&Seehausen_2010 Fig2 Pundamilia_nyererei_Pundamilia_pundamilia Pundamilia Pundamilia_nyererei Pundamilia_pundamilia Pundamilia_nyererei_Pundamilia_pundamilia Yes morphology % red cover of body 26.2272727 8.3349310 6.8750000 6.0194996 7.1000000 5.1224994 2.4500000 1.6575584 4 4 3 3 11 24 5 20 2.966712815 Viable
s18 Monti et al_2001 table1 Spodoptera_descoinsi_Spodoptera_latifascia Spodoptera Spodoptera_descoinsi Spodoptera_latifascia Spodoptera_descoinsi_Spodoptera_latifascia Yes morphology clasper shape 977.9300000 56.8600000 1097.0000000 42.5200000 1080.8300000 66.6200000 1117.0000000 70.4700000 <15 <15 <15 <15 <15 <15 <15 <15 30 30 30 30 -0.480020782 Viable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Complex 2_meanduration 0.0350000 0.0120277 0.0345000 0.0021213 0.0381667 0.0110529 4 2 6 -0.551411061 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Complex 2_peakfrequstart 88243.2360000 13841.1853318 74950.0000000 636.3961031 72556.1870000 12617.0280666 4 2 6 -0.383334895 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Complex 2_minfreqstart 86607.4352500 13818.4480691 73428.1250000 667.3320247 69262.5583333 11355.7727478 4 2 6 -0.340599520 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Complex 2_maxfrequstart 91795.0325000 12995.6534046 77565.6250000 48.6135912 78189.1510000 12300.4108541 4 2 6 -0.437719496 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Complex 2_bandwstart 5143.7662500 2045.3369815 4068.7500000 662.9126074 8864.5688333 4581.0818004 4 2 6 0.153511885 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Complex 2_entropystart 0.2057500 0.0209185 0.1930000 0.0325269 0.2135000 0.0154370 4 2 6 -0.627869204 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Complex 2_peakfrequend 74352.4027500 5053.6317335 73462.5000000 18685.2966929 70818.2011667 7761.6449976 4 2 6 -0.609809630 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Complex 2_minfreqend 72380.2272500 5077.6205582 71778.1250000 18353.8403892 68704.3900000 7683.0440288 4 2 6 -0.604541730 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Complex 2_maxfrequend 77172.7707500 5578.8877045 76237.5000000 19498.4694912 73259.6543333 7707.3985467 4 2 6 -0.604670211 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Complex 2_bandwend 4737.1212500 658.3624192 4400.0000000 1131.3708499 4521.8338333 641.0389018 4 2 6 -0.613179660 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Complex 2_entropyend 0.2087500 0.0171925 0.2030000 0.0367696 0.2091667 0.0126399 4 2 6 -0.681749308 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Complex 2_peakfrequcentre 85535.6927500 9125.8577495 62084.3750000 37454.5623160 61978.2051667 9275.5460027 4 2 6 -0.188621563 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Complex 2_minfreqcenter 80507.1970000 8382.7388396 69421.8750000 21244.1393573 61213.2866667 9007.7450086 4 2 6 -0.262814215 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Complex 2_maxfreqcenter 90638.4525000 8209.6444716 95231.2500000 2713.5222728 71257.7506667 7370.4746511 4 2 6 -0.314270540 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Complex 2_bandwcentre 10071.6775000 4429.0518530 25728.1250000 23931.1451258 9988.7530000 6829.4344123 4 2 6 -0.672086435 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Complex 2_entropycentre 0.2252500 0.0343256 0.1705000 0.0912168 0.2091667 0.0341433 4 2 6 -0.570718267 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Complex 2_peakfrequmax 80739.4265000 5303.4742393 82650.0000000 3676.9552622 68118.2983333 9187.5342106 4 2 6 -0.423003987 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Complex 2_minfreqmax 79202.7922500 5361.1342413 81371.8750000 2930.0737245 66305.2156667 9378.6307948 4 2 6 -0.411048644 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Complex 2_maxfrequmax 84045.2057500 4837.5806504 85321.8750000 3707.8911838 72361.4995000 9750.2056443 4 2 6 -0.454272527 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Complex 2_bandwmax 4802.3810000 1332.0316481 3918.7500000 733.6232855 6007.6146667 2379.1891824 4 2 6 -0.339929894 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Complex 2_entropymax 0.1950000 0.0107393 0.1925000 0.0162635 0.2043333 0.0116390 4 2 6 -0.612808308 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Complex 2_FAC2_1 1.9098486 1.8018551 0.4389270 1.0762664 0.4527336 1.2603555 4 2 6 1.532358568 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Complex 2_FAC1_3 1.4977934 0.9941282 1.3129292 0.3134363 3.8618017 3.4780153 4 2 6 0.774030955 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Complex 2_FAC1_4 0.4874387 1.1538739 -0.6730174 2.7297053 0.5559659 0.6476944 4 2 6 -0.482209844 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped Inverted_meanduration 0.0247500 0.0116154 0.0330000 0.0431429 0.0216597 4 1 7 0.171093472 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped Inverted_peakfrequstart 76228.5715000 13271.3152368 75540.0000000 54580.9524286 7151.3235607 4 1 7 -0.170291706 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped Inverted_minfreqstart 74332.1427500 12615.6156919 74460.0000000 53274.7618571 6927.0360415 4 1 7 -0.171786727 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped Inverted_maxfrequstart 78808.3332500 12749.5641588 78860.0000000 57440.0001429 7073.5971258 4 1 7 -0.197667775 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped Inverted_bandwstart 4411.9050000 626.2642551 4340.0000000 4110.0000000 600.3116768 4 1 7 -0.575640926 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped Inverted_entropystart 0.2115000 0.0157586 0.2210000 0.2022857 0.0233503 4 1 7 -0.616211094 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped Inverted_peakfrequend 75334.5240000 11042.2134461 79060.0000000 58608.0951429 6273.4698049 4 1 7 -0.298111985 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped Inverted_minfreqend 74025.0000000 11169.4150847 78160.0000000 57369.0475714 6615.9479668 4 1 7 -0.292209258 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped Inverted_maxfrequend 77971.4285000 11022.6693431 82940.0000000 61825.7142857 6094.1748961 4 1 7 -0.327442700 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped Inverted_bandwend 3878.5715000 836.3032833 4740.0000000 4394.2855714 1103.0087703 4 1 7 -0.492536481 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped Inverted_entropyend 0.1935000 0.0287112 0.2140000 0.2121429 0.0128508 4 1 7 -0.543143026 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped Inverted_peakfrequcentre 84771.4285000 11250.2360323 90260.0000000 65132.8571429 6639.2899236 4 1 7 -0.278914487 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped Inverted_minfreqcenter 82939.2857500 11362.3125349 89020.0000000 63461.4287143 7232.0898611 4 1 7 -0.272526799 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped Inverted_maxfreqcenter 87214.2857500 11278.1558979 92820.0000000 68880.9524286 4518.6205675 4 1 7 -0.321334970 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped Inverted_bandwcentre 4239.2857500 426.0486747 3800.0000000 5404.2857143 4186.7844922 4 1 7 -0.310847230 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped Inverted_entropycentre 0.1967500 0.0115289 0.1930000 0.1890000 0.0072801 4 1 7 -0.622922047 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped Inverted_peakfrequmax 81715.4760000 10451.3541605 85680.0000000 64371.4285714 7250.3760465 4 1 7 -0.317353264 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped Inverted_minfreqmax 80088.0952500 10219.5703381 84440.0000000 62977.1428571 7156.8075149 4 1 7 -0.314608750 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped Inverted_maxfrequmax 84541.6665000 10896.6653124 88540.0000000 66872.3810000 7126.6805948 4 1 7 -0.323691569 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped Inverted_bandwmax 4390.4762500 1075.8253068 4080.0000000 3884.2855714 142.6563258 4 1 7 -0.496139807 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped Inverted_entropymax 0.1997500 0.0209821 0.1990000 0.1897381 0.0127089 4 1 7 -0.605617070 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped Inverted_FAC1_2 0.0641031 0.7688575 0.8763980 0.3896661 1.0029075 4 1 7 2.095052447 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped_meanduration 0.0260000 0.0116619 0.0376000 0.0112827 0.0354444 0.0097482 4 5 9 -0.207537553 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped_peakfrequstart 80479.7617500 12733.6564666 79085.4762000 3447.3265538 65840.7107778 5732.7881166 4 5 9 -0.375584876 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped_minfreqstart 79164.8807500 12512.0095023 77460.9522000 3600.6844370 63745.1970000 5888.2100068 4 5 9 -0.351138435 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped_maxfrequstart 82837.5000000 12669.1982077 81530.7144000 3665.7522184 68163.0446667 5734.4353543 4 5 9 -0.384501627 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped_bandwstart 3639.8810000 853.3854609 4006.1906000 651.1667981 4360.5252222 453.4732575 4 5 9 -0.406584124 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped_entropystart 0.1835000 0.0233880 0.1972000 0.0226208 0.2200000 0.0225278 4 5 9 -0.405396032 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped_peakfrequend 79257.1427500 12462.3047588 80213.0952000 4487.0077220 66126.1151111 6271.9991028 4 5 9 -0.405825913 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped_minfreqend 77598.8095000 12226.8021838 78693.8096000 4816.5305116 64482.5417778 5952.0201006 4 5 9 -0.399628204 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped_maxfrequend 81726.7857500 12753.0766460 83136.1904000 4656.4245579 69003.3801111 5730.3578037 4 5 9 -0.424166620 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped_bandwend 4083.3335000 786.2241599 4392.8570000 725.5012887 4462.8988889 468.0169154 4 5 9 -0.547914084 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped_entropyend 0.1977500 0.0196193 0.2048000 0.0207292 0.2275556 0.0441478 4 5 9 -0.468581058 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped_peakfrequcentre 74933.3332500 10968.5408399 71673.8094000 3009.5076498 59479.1160000 5400.4655878 4 5 9 -0.329059247 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped_minfreqcenter 72616.6667500 12624.6233365 70144.2856000 2999.7169555 57936.3224444 5682.7417545 4 5 9 -0.336951003 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped_maxfreqcenter 80083.9285000 8479.2792799 74386.4286000 3202.4808429 62278.1645556 5499.6658025 4 5 9 -0.297497989 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped_bandwcentre 7431.5477500 6279.7280238 4214.0476000 363.2867758 4307.3395556 818.6217348 4 5 9 0.155263093 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped_entropycentre 0.1990000 0.0053541 0.1952000 0.0056303 0.2087778 0.0237106 4 5 9 -0.610940719 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped_peakfrequmax 79097.6192500 11822.7651521 76354.7620000 5142.8431679 63787.8418889 5091.3037702 4 5 9 -0.353477742 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped_minfreqmax 77244.0475000 11659.2282489 74737.8572000 5116.6142024 62107.5704444 4788.4915589 4 5 9 -0.348884971 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped_maxfrequmax 81376.1905000 11690.8610379 78997.6190000 5192.4923151 66376.4416667 5054.8521007 4 5 9 -0.371005446 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped_bandwmax 4088.6907500 268.9063550 4235.0000000 620.6398924 4223.3141111 397.7357504 4 5 9 -0.634923093 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped_entropymax 0.1930000 0.0054772 0.1956000 0.0098641 0.2045556 0.0125111 4 5 9 -0.595254902 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Upsweep_meanduration 0.0285000 0.0063509 0.0276000 0.0031305 0.0351000 0.0073401 4 5 10 -0.363987192 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Upsweep_peakfrequstart 69339.9377500 6362.5905607 66031.8856000 3929.1367989 54773.7979000 4196.1911989 4 5 10 -0.321611224 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Upsweep_minfreqstart 68133.1495000 6257.9552643 64796.1706000 4082.6666572 53275.0191000 4213.6700004 4 5 10 -0.305920148 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Upsweep_maxfrequstart 71765.7477500 6142.9162222 68733.4816000 3952.8608450 57315.1191000 4048.9568152 4 5 10 -0.338502181 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Upsweep_bandwstart 3589.9292500 176.6865194 3887.3656000 476.5605623 3994.0754000 380.9553189 4 5 10 -0.520505343 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Upsweep_entropystart 0.1867500 0.0066521 0.1906000 0.0158524 0.2022000 0.0143279 4 5 10 -0.562390082 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Upsweep_peakfrequend 80755.2170000 7130.3793512 78555.2896000 5371.4415642 66458.1019000 4740.6017565 4 5 10 -0.384697922 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Upsweep_minfreqend 79211.8740000 7021.7575623 76984.6620000 5382.1778808 64829.2506000 4552.7376009 4 5 10 -0.376198029 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Upsweep_maxfrequend 83357.7775000 7015.1036046 81298.9990000 5595.8063179 69166.6400000 4648.9534970 4 5 10 -0.397370659 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Upsweep_bandwend 4100.5467500 191.5042202 4258.5490000 361.0614413 4288.1656000 429.1656564 4 5 10 -0.615910971 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Upsweep_entropyend 0.1982500 0.0082614 0.2010000 0.0125499 0.2114000 0.0152184 4 5 10 -0.585899621 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Upsweep_peakfrequcentre 74106.6220000 7044.5184840 73891.5844000 5092.2358605 61283.1031000 3445.7123977 4 5 10 -0.392168430 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Upsweep_minfreqcenter 72668.0320000 6267.5002741 71986.6968000 4961.9873412 59578.0253000 3392.0761680 4 5 10 -0.378900511 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Upsweep_maxfreqcenter 78169.5640000 5725.8571623 76532.0698000 5240.1316395 63854.9729000 3631.4868123 4 5 10 -0.373276772 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Upsweep_bandwcentre 5460.9155000 1647.2090987 4501.4542000 316.2865754 4241.4512000 460.9409794 4 5 10 -0.295577798 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Upsweep_entropycentre 0.2055000 0.0124499 0.2020000 0.0077782 0.2016000 0.0121033 4 5 10 -0.655308316 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Upsweep_peakfrequmax 77823.1835000 5399.8126400 75780.1022000 5415.3370781 63366.8131000 3563.3066643 4 5 10 -0.368296771 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Upsweep_minfreqmax 75957.8212500 5436.7383936 74190.8194000 5410.9982527 61786.7749000 3572.0160930 4 5 10 -0.366772281 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Upsweep_maxfrequmax 80373.0087500 5426.3663453 78304.8670000 5489.1644712 65856.5116000 3558.8589776 4 5 10 -0.377998932 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Upsweep_bandwmax 4377.1182500 458.3771312 4075.2264000 103.6274969 4038.5590000 95.8375937 4 5 10 -0.560824944 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Upsweep_entropymax 0.1977500 0.0121758 0.1922000 0.0046583 0.1960000 0.0109747 4 5 10 -0.671129264 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Downsweep_meanduration 0.0267500 0.0025000 0.0268000 0.0038987 0.0344000 0.0176522 4 5 10 -0.297408999 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Downsweep_peakfrequstart 92946.9280000 15749.6397527 86481.4286000 5235.4356333 74913.1969000 7786.3062625 4 5 10 -0.352586813 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Downsweep_minfreqstart 91265.4315000 15635.4785025 85101.1546000 5126.9975016 72762.6818000 8026.5298721 4 5 10 -0.335843653 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Downsweep_maxfrequstart 95250.4370000 15611.6348854 88932.3952000 5456.0298891 77138.1818000 7532.7019771 4 5 10 -0.359960658 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Downsweep_bandwstart 3938.6365000 407.4663826 3770.7360000 571.0050616 4327.9697000 1129.8378295 4 5 10 -0.539628821 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Downsweep_entropystart 0.1940000 0.0162686 0.1890000 0.0151162 0.2120000 0.0258844 4 5 10 -0.548155483 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Downsweep_peakfrequend 80321.3132500 13264.1601325 76316.7246000 3882.0213419 66018.2273000 6019.6800990 4 5 10 -0.382767555 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Downsweep_minfreqend 78858.0547500 13220.5889301 74963.2754000 4014.2011731 64436.2727000 5953.7214161 4 5 10 -0.373728310 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Downsweep_maxfrequend 83015.5642500 13098.4743972 79279.4950000 3972.5831489 68731.5455000 5833.3199357 4 5 10 -0.393987321 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Downsweep_bandwend 4104.4317500 319.2320090 4266.2626000 160.5837063 4239.1515000 376.5780209 4 5 10 -0.635076378 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Downsweep_entropyend 0.1957500 0.0127377 0.1992000 0.0032711 0.2177000 0.0218228 4 5 10 -0.521121428 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Downsweep_peakfrequcentre 85783.7080000 13616.0068270 80867.3596000 5707.2122076 65722.3939000 5496.8625711 4 5 10 -0.274509367 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Downsweep_minfreqcenter 84079.9412500 13437.8479318 79064.9062000 5758.6121464 64018.1667000 5500.6339410 4 5 10 -0.264941612 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Downsweep_maxfreqcenter 88618.9480000 13627.6886529 83648.0088000 5894.4675948 68351.4394000 5563.6384045 4 5 10 -0.284838893 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Downsweep_bandwcentre 4503.1745000 390.7571406 4530.2886000 282.0421900 4283.8030000 426.1499071 4 5 10 -0.607897412 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Downsweep_entropycentre 0.2027500 0.0092871 0.2036000 0.0094499 0.2030000 0.0185053 4 5 10 -0.682922581 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Downsweep_peakfrequmax 86744.4337500 13629.4541780 80625.3968000 5025.9533091 66385.7122000 5290.0326237 4 5 10 -0.272822757 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Downsweep_minfreqmax 84959.1095000 13504.3981075 79065.7430000 5016.1123507 64919.6969000 5355.5238651 4 5 10 -0.270459052 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Downsweep_maxfrequmax 89437.1925000 13622.5958524 83594.9494000 5076.7807417 68886.5151000 5319.5671675 4 5 10 -0.282693138 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Downsweep_bandwmax 4434.5437500 323.8048150 4497.0850000 312.9490788 3952.0908000 142.0981267 4 5 10 -0.507412501 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Downsweep_entropymax 0.1990000 0.0115181 0.2004000 0.0069498 0.1904000 0.0112270 4 5 10 -0.616775096 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Downsweep_FAC2_1 2.0886949 1.1136315 1.5887848 0.3969399 0.8389634 0.6739541 4 5 10 0.720101036 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Constant Modulated_meanduration 0.0265000 0.0106615 0.0292000 0.0046043 0.0490000 0.0188797 4 5 10 0.261944974 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Constant Modulated_peakfrequstart 69169.0910000 9324.4840586 72231.8094000 4372.7725516 58622.4861000 4177.5985187 4 5 10 -0.430005096 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Constant Modulated_minfreqstart 67626.3637500 9012.4152325 70881.4066000 4153.6520615 57128.3611000 4289.6169090 4 5 10 -0.424981568 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Constant Modulated_maxfrequstart 71406.1362500 8903.2731162 74543.2748000 4406.7481866 60936.9862000 4080.3940669 4 5 10 -0.440621038 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Constant Modulated_bandwstart 3756.6667500 157.6212831 3607.1428000 355.7839191 3761.9722000 634.3257829 4 5 10 -0.682646883 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Constant Modulated_entropystart 0.1860000 0.0040825 0.1856000 0.0107842 0.2004000 0.0206839 4 5 10 -0.569964796 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Constant Modulated_peakfrequend 69355.7577500 7543.9312104 73531.9192000 2979.5723937 59648.3194000 4627.5588424 4 5 10 -0.452573981 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Constant Modulated_minfreqend 67679.9242500 7694.1337933 72042.2784000 2956.8202038 58407.7222000 4528.6555691 4 5 10 -0.457875137 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Constant Modulated_maxfrequend 72289.7727500 7207.9161126 75923.6484000 3046.3029627 62455.1249000 4470.2205884 4 5 10 -0.459580398 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Constant Modulated_bandwend 4533.4850000 626.2282663 3833.2748000 260.5736903 4000.4722000 271.3453083 4 5 10 -0.492166034 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Constant Modulated_entropyend 0.2062500 0.0107819 0.1920000 0.0083964 0.2032000 0.0143201 4 5 10 -0.661873231 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Constant Modulated_peakfrequcentre 68660.6817500 7663.4948537 72021.6116000 3615.6610863 59662.3749000 4149.6050515 4 5 10 -0.468451168 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Constant Modulated_minfreqcenter 67142.2727500 7703.6470736 70267.8316000 3511.0302351 58124.8194000 4183.0463575 4 5 10 -0.462681393 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Constant Modulated_maxfreqcenter 71632.0455000 7409.1498507 74567.8900000 3563.3700105 62026.3194000 4196.2300849 4 5 10 -0.463046975 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Constant Modulated_bandwcentre 4444.6212500 673.9336392 4261.2308000 595.5497093 3878.5416000 177.2936857 4 5 10 -0.474981416 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Constant Modulated_entropycentre 0.1990000 0.0134412 0.2014000 0.0173436 0.1961000 0.0112195 4 5 10 -0.662209346 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Constant Modulated_peakfrequmax 68920.4545000 7723.1945601 73048.2564000 3656.6152656 60169.5138000 4456.3801999 4 5 10 -0.475671847 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Constant Modulated_minfreqmax 67252.9545000 7730.3144970 71570.0880000 3681.7389827 58666.8750000 4456.7669770 4 5 10 -0.474441949 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Constant Modulated_maxfrequmax 71630.7577500 7551.5296524 75444.2492000 3592.5206245 62560.9861000 4458.4226262 4 5 10 -0.476294880 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Constant Modulated_bandwmax 4330.1515000 407.1581403 3852.3444000 191.5057684 3868.9027000 174.3981447 4 5 10 -0.511337687 Inviable
s19 Musolf et al_2015 S2 musculus.1 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Constant Modulated_entropymax 0.1997500 0.0156498 0.1892000 0.0093381 0.1915000 0.0102008 4 5 10 -0.619853979 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Complex 2_meanduration 0.0350000 0.0120277 0.0381667 0.0066458 0.0425000 0.0275772 4 6 2 -0.385768178 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Complex 2_peakfrequstart 88243.2360000 13841.1853318 73305.6713333 4769.9467214 66238.6365000 12885.4138334 4 6 2 -0.243020520 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Complex 2_minfreqstart 86607.4352500 13818.4480691 71600.6366667 4899.4887991 65145.4545000 13795.0105409 4 6 2 -0.246208851 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Complex 2_maxfrequstart 91795.0325000 12995.6534046 75512.6351667 4620.4944652 69802.2725000 13785.3684328 4 6 2 -0.262953915 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Complex 2_entropystart 0.2057500 0.0209185 0.1780000 0.0144914 0.2025000 0.0035355 4 6 2 -0.660296545 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Complex 2_peakfrequend 74352.4027500 5053.6317335 77592.3225000 10448.6713702 61843.1820000 5666.4963576 4 6 2 -0.401081351 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Complex 2_minfreqend 72380.2272500 5077.6205582 75370.5631667 9716.7533828 59870.4545000 5062.2417932 4 6 2 -0.392554591 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Complex 2_maxfrequend 77172.7707500 5578.8877045 79990.5866667 10512.6172950 65202.2725000 4451.5589212 4 6 2 -0.425204686 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Complex 2_bandwend 4737.1212500 658.3624192 4577.4498333 867.7424719 5268.1820000 662.1093341 4 6 2 -0.521158274 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Complex 2_entropyend 0.2087500 0.0171925 0.1993333 0.0194182 0.2220000 0.0028284 4 6 2 -0.590032462 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Complex 2_peakfrequcentre 85535.6927500 9125.8577495 77685.0115000 5235.8011518 63693.1820000 40385.4393138 4 6 2 -0.230662785 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Complex 2_minfreqcenter 80507.1970000 8382.7388396 75118.2870000 4715.1801229 67679.5455000 33050.8137127 4 6 2 -0.417487596 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Complex 2_maxfreqcenter 90638.4525000 8209.6444716 85149.2475000 7210.7901272 96740.9090000 2886.2811874 4 6 2 -0.584460074 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Complex 2_bandwcentre 10071.6775000 4429.0518530 9980.9800000 5931.1228099 29015.9090000 35872.8125297 4 6 2 0.944963973 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Complex 2_entropycentre 0.2252500 0.0343256 0.2113333 0.0233467 0.1615000 0.0544472 4 6 2 -0.172364334 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Complex 2_peakfrequmax 80739.4265000 5303.4742393 78668.1135000 5702.1882220 70011.3635000 12075.4555425 4 6 2 -0.465225358 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Complex 2_minfreqmax 79202.7922500 5361.1342413 76413.0593333 6057.2386935 68222.7275000 12554.3591664 4 6 2 -0.454960469 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Complex 2_maxfrequmax 84045.2057500 4837.5806504 81311.1883333 5595.5060910 72500.0000000 12020.8152802 4 6 2 -0.457217796 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Complex 2_bandwmax 4802.3810000 1332.0316481 4874.2476667 1278.9380970 4263.6365000 514.2596701 4 6 2 -0.501544967 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Complex 2_entropymax 0.1950000 0.0107393 0.1935000 0.0051284 0.1985000 0.0049497 4 6 2 -0.657419957 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Complex 2_FAC2_1 1.9098486 1.8018551 0.0221902 0.5561929 0.0761514 1.0631389 4 6 2 4.278011534 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Complex 2_FAC1_3 1.4977934 0.9941282 0.9259184 1.1546713 2.3807529 3.0564478 4 6 2 0.028976672 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped_meanduration 0.0260000 0.0116619 0.0317143 0.0024300 0.0331000 0.0117988 4 7 10 -0.312943144 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped_peakfrequstart 80479.7617500 12733.6564666 77879.0675714 4602.9590631 69479.9405000 11645.2813142 4 7 10 -0.458450927 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped_minfreqstart 79164.8807500 12512.0095023 76067.6807143 4701.9548514 67727.2024000 11534.8704547 4 7 10 -0.444469588 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped_maxfrequstart 82837.5000000 12669.1982077 80050.3137143 4775.5257050 71814.9405000 11778.6104092 4 7 10 -0.464888239 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped_bandwstart 3639.8810000 853.3854609 3939.8922857 433.8022877 4029.5834000 680.4207605 4 7 10 -0.528156800 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped_entropystart 0.1835000 0.0233880 0.1830000 0.0123018 0.1937000 0.0344353 4 7 10 -0.601498400 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped_peakfrequend 79257.1427500 12462.3047588 81017.5178571 6016.4509795 71188.0953000 14556.4775881 4 7 10 -0.519438990 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped_minfreqend 77598.8095000 12226.8021838 79011.1092857 5757.6575979 69773.2143000 14066.5281763 4 7 10 -0.521087133 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped_maxfrequend 81726.7857500 12753.0766460 83337.7177143 6083.9637972 73858.9881000 14204.2004101 4 7 10 -0.528908317 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped_bandwend 4083.3335000 786.2241599 4277.4301429 683.3155854 4027.2619000 688.5740425 4 7 10 -0.663523377 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped_entropyend 0.1977500 0.0196193 0.1867143 0.0146483 0.2027000 0.0311450 4 7 10 -0.646739879 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped_peakfrequcentre 74933.3332500 10968.5408399 70775.6034286 3871.4823805 65815.0594000 11251.9001331 4 7 10 -0.484970523 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped_minfreqcenter 72616.6667500 12624.6233365 69188.4248571 3898.1055085 64420.1786000 11199.3646633 4 7 10 -0.500346412 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped_maxfreqcenter 80083.9285000 8479.2792799 73324.4728571 4012.8599083 68504.0477000 10935.3646195 4 7 10 -0.444257818 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped_bandwcentre 7431.5477500 6279.7280238 4103.1570000 295.9083431 4036.2500000 473.3382165 4 7 10 0.255387341 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped_entropycentre 0.1990000 0.0053541 0.1841429 0.0055806 0.1986000 0.0183012 4 7 10 -0.681721500 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped_peakfrequmax 79097.6192500 11822.7651521 74312.5190000 3267.9708291 69627.7381000 11480.9355266 4 7 10 -0.488405934 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped_minfreqmax 77244.0475000 11659.2282489 72715.0254286 3256.1742969 68056.9047000 11431.6737156 4 7 10 -0.489783064 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped_maxfrequmax 81376.1905000 11690.8610379 76883.3712857 3125.7538591 72044.1071000 11604.9769219 4 7 10 -0.497209421 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped_bandwmax 4088.6907500 268.9063550 4128.2158571 202.3831040 3950.5357000 342.2510779 4 7 10 -0.631876020 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound U Shaped_entropymax 0.1930000 0.0054772 0.1828571 0.0047759 0.1946000 0.0209242 4 7 10 -0.672104203 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Upsweep_meanduration 0.0285000 0.0063509 0.0300000 0.0036968 0.0274000 0.0056214 4 7 10 -0.624193998 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Upsweep_peakfrequstart 69339.9377500 6362.5905607 68451.6210000 2875.9266220 62809.4284000 7177.9005225 4 7 10 -0.532463639 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Upsweep_minfreqstart 68133.1495000 6257.9552643 67045.1720000 2746.4746641 61456.5655000 7116.6283122 4 7 10 -0.525967783 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Upsweep_maxfrequstart 71765.7477500 6142.9162222 70854.8157143 2947.6970887 65648.8367000 7248.4481801 4 7 10 -0.547602042 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Upsweep_bandwstart 3589.9292500 176.6865194 3775.6927143 345.8361665 4137.3085000 395.3846050 4 7 10 -0.466236524 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Upsweep_entropystart 0.1867500 0.0066521 0.1787143 0.0085968 0.2046000 0.0203372 4 7 10 -0.544215608 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Upsweep_peakfrequend 80755.2170000 7130.3793512 84010.6845714 7798.9189014 72124.2288000 8826.0091312 4 7 10 -0.510720144 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Upsweep_minfreqend 79211.8740000 7021.7575623 82066.5910000 7545.2449096 70563.0160000 8746.6720876 4 7 10 -0.506734664 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Upsweep_maxfrequend 83357.7775000 7015.1036046 86438.1841429 7823.3391056 74765.7748000 8842.4361599 4 7 10 -0.517267585 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Upsweep_bandwend 4100.5467500 191.5042202 4319.4790000 348.1816172 4153.6997000 370.0441849 4 7 10 -0.664983337 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Upsweep_entropyend 0.1982500 0.0082614 0.1891429 0.0079042 0.2075000 0.0245956 4 7 10 -0.614580556 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Upsweep_peakfrequcentre 74106.6220000 7044.5184840 72854.8815714 4026.8954597 70103.3933000 7576.5492005 4 7 10 -0.599283815 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Upsweep_minfreqcenter 72668.0320000 6267.5002741 70949.8125714 3823.1241531 68409.5260000 7641.2047793 4 7 10 -0.591804601 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Upsweep_maxfreqcenter 78169.5640000 5725.8571623 75534.1190000 4229.4249557 72564.2708000 7651.9750334 4 7 10 -0.570212770 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Upsweep_bandwcentre 5460.9155000 1647.2090987 4543.9688571 473.1665573 4121.6782000 165.3409998 4 7 10 -0.251456699 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Upsweep_entropycentre 0.2055000 0.0124499 0.1920000 0.0080416 0.1996000 0.0182160 4 7 10 -0.639951570 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Upsweep_peakfrequmax 77823.1835000 5399.8126400 75226.5405714 3353.0057009 70628.7162000 7823.2305707 4 7 10 -0.535410602 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Upsweep_minfreqmax 75957.8212500 5436.7383936 73565.3675714 3374.9969637 69142.0198000 7795.7957098 4 7 10 -0.540011404 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Upsweep_maxfrequmax 80373.0087500 5426.3663453 77772.7288571 3462.0600997 73062.2498000 7849.4368575 4 7 10 -0.537930443 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Upsweep_bandwmax 4377.1182500 458.3771312 4169.4832857 128.2774426 3893.3592000 143.5696943 4 7 10 -0.504427057 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Upsweep_entropymax 0.1977500 0.0121758 0.1842857 0.0035923 0.1923000 0.0179075 4 7 10 -0.641774811 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Upsweep_FAC1_1 1.0730254 0.6319905 1.1317147 0.6998538 0.3490031 0.8701206 4 7 10 1.045142241 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Downsweep_meanduration 0.0267500 0.0025000 0.0188571 0.0048107 0.0342000 0.0090529 4 7 10 -0.306390184 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Downsweep_peakfrequstart 92946.9280000 15749.6397527 83172.8458571 6591.5365310 74608.2984000 9917.5386682 4 7 10 -0.346305090 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Downsweep_minfreqstart 91265.4315000 15635.4785025 81643.7951429 6791.6267628 73061.0328000 9813.6525389 4 7 10 -0.342146350 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Downsweep_maxfrequstart 95250.4370000 15611.6348854 85390.5380000 6887.5176862 76974.2429000 9878.5598701 4 7 10 -0.356683699 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Downsweep_bandwstart 3938.6365000 407.4663826 3697.4025714 538.0658783 3869.6487000 469.9430250 4 7 10 -0.657602743 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Downsweep_entropystart 0.1940000 0.0162686 0.1780000 0.0167929 0.1974000 0.0245728 4 7 10 -0.658060052 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Downsweep_peakfrequend 80321.3132500 13264.1601325 75947.5367143 5476.7229011 66474.0521000 8898.1472848 4 7 10 -0.393365840 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Downsweep_minfreqend 78858.0547500 13220.5889301 74498.0982857 5701.1827887 64969.0043000 8816.5109640 4 7 10 -0.386410243 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Downsweep_maxfrequend 83015.5642500 13098.4743972 78965.3731429 6242.7990745 69391.8936000 8906.2629017 4 7 10 -0.408715036 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Downsweep_bandwend 4104.4317500 319.2320090 4429.1331429 1120.8845735 4364.9190000 441.7075033 4 7 10 -0.590044307 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Downsweep_entropyend 0.1957500 0.0127377 0.2000000 0.0380701 0.2101000 0.0247855 4 7 10 -0.575853895 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Downsweep_peakfrequcentre 85783.7080000 13616.0068270 77128.8085714 6248.6809489 69161.7468000 8267.9554886 4 7 10 -0.353075706 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Downsweep_minfreqcenter 84079.9412500 13437.8479318 75565.8524286 6160.4471028 67649.9982000 8204.8806697 4 7 10 -0.349934308 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Downsweep_maxfreqcenter 88618.9480000 13627.6886529 79822.0831429 6243.4272218 71784.9698000 8317.2169852 4 7 10 -0.360331315 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Downsweep_bandwcentre 4503.1745000 390.7571406 4201.2110000 195.3805990 4089.9495000 253.4433097 4 7 10 -0.536569806 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Downsweep_entropycentre 0.2027500 0.0092871 0.1898571 0.0052418 0.1996000 0.0182221 4 7 10 -0.660702597 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Downsweep_peakfrequmax 86744.4337500 13629.4541780 77734.9567143 5425.7783009 70111.6135000 8434.1731776 4 7 10 -0.356931593 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Downsweep_minfreqmax 84959.1095000 13504.3981075 76064.7290000 5169.3925630 68609.6506000 8448.2002277 4 7 10 -0.355608394 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Downsweep_maxfrequmax 89437.1925000 13622.5958524 80257.0294286 5557.8365151 72587.0407000 8452.0702898 4 7 10 -0.363289184 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Downsweep_bandwmax 4434.5437500 323.8048150 4156.9417143 513.0828757 3949.5721000 94.2193667 4 7 10 -0.506430562 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Downsweep_entropymax 0.1990000 0.0115181 0.1850000 0.0129615 0.1937000 0.0171727 4 7 10 -0.643242225 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Downsweep_FAC2_1 2.0886949 1.1136315 1.2441253 0.5051707 0.7618315 0.6656533 4 7 10 0.868647093 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Frequ Modulated Downsweep_FAC1_2 0.0126201 0.5416632 0.4169407 0.6986566 0.2071921 1.1713853 4 7 10 3.625400558 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Constant Modulated_meanduration 0.0265000 0.0106615 0.0270000 0.0071880 0.0310000 0.0078031 4 7 10 -0.443241065 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Constant Modulated_peakfrequstart 69169.0910000 9324.4840586 63660.0515301 25465.5528228 66991.5600000 8194.9523706 4 7 10 -0.635551346 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Constant Modulated_minfreqstart 67626.3637500 9012.4152325 62489.4885774 24999.7828272 65844.5850000 8115.5487360 4 7 10 -0.643694361 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Constant Modulated_maxfrequstart 71406.1362500 8903.2731162 65671.9343991 26271.1332349 69454.7217000 8199.8533693 4 7 10 -0.642141704 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Constant Modulated_bandwstart 3756.6667500 157.6212831 3144.0522479 1261.7363913 3561.5091000 715.7415371 4 7 10 -0.602650831 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Constant Modulated_entropystart 0.1860000 0.0040825 0.4902256 1.2484114 0.1876000 0.0312915 4 7 10 -0.671627672 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Constant Modulated_peakfrequend 69355.7577500 7543.9312104 64144.7233062 25832.1297413 67522.4211000 8547.3791192 4 7 10 -0.643557662 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Constant Modulated_minfreqend 67679.9242500 7694.1337933 62735.7946403 25225.2407203 66277.7084000 8406.3181878 4 7 10 -0.652573598 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Constant Modulated_maxfrequend 72289.7727500 7207.9161126 66204.7049575 26631.2674949 70072.8344000 8466.4939927 4 7 10 -0.636845155 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Constant Modulated_bandwend 4533.4850000 626.2282663 3436.0465660 1511.7179335 3743.4125000 411.9136739 4 7 10 -0.389869426 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Constant Modulated_entropyend 0.2062500 0.0107819 0.4967598 1.2467428 0.1918000 0.0224935 4 7 10 -0.572941878 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Constant Modulated_peakfrequcentre 68660.6817500 7663.4948537 63366.9744458 25500.1528586 68809.8620000 8155.6970594 4 7 10 -0.681477695 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Constant Modulated_minfreqcenter 67142.2727500 7703.6470736 61936.1854557 24915.9881117 67349.2843000 8118.6006467 4 7 10 -0.680079017 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Constant Modulated_maxfreqcenter 71632.0455000 7409.1498507 65518.2060007 26340.0697982 71150.9535000 8127.7818884 4 7 10 -0.674441053 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Constant Modulated_bandwcentre 4444.6212500 673.9336392 3594.6877006 1395.2722123 3784.8907000 131.2380772 4 7 10 -0.437333862 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Constant Modulated_entropycentre 0.1990000 0.0134412 0.4995162 1.2458998 0.1901000 0.0166897 4 7 10 -0.614346287 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Constant Modulated_peakfrequmax 68920.4545000 7723.1945601 63978.4102444 25657.4176630 68911.7817000 8343.3168913 4 7 10 -0.684626797 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Constant Modulated_minfreqmax 67252.9545000 7730.3144970 62686.6273322 25145.8487055 67480.7775000 8341.8147142 4 7 10 -0.679611707 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Constant Modulated_maxfrequmax 71630.7577500 7551.5296524 66036.0423216 26494.0638733 71293.2103000 8344.5429680 4 7 10 -0.677545229 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Constant Modulated_bandwmax 4330.1515000 407.1581403 3352.2286112 1328.7828084 3787.5374000 147.5658605 4 7 10 -0.478599456 Inviable
s19 Musolf et al_2015 S2 musculus.3 Mus Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus Yes sound Constant Modulated_entropymax 0.1997500 0.0156498 0.4928359 1.2476990 0.1878000 0.0161644 4 7 10 -0.589802962 Inviable
s20 Paallysaho et al_2003 table1 Drosophila_montana_Drosophila_virilis Drosophila Drosophila_montana Drosophila_virilis Drosophila_montana_Drosophila_virilis Yes sound PI 20.7000000 2.7100000 20.0000000 2.7400000 19.7000000 1.2500000 10 10 10 5 10 -0.608554123 Inviable
s20 Paallysaho et al_2003 table1 Drosophila_montana_Drosophila_virilis Drosophila Drosophila_montana Drosophila_virilis Drosophila_montana_Drosophila_virilis Yes sound IPI 35.7000000 2.1100000 30.2000000 3.2700000 19.7000000 1.2500000 10 10 10 5 10 0.230918551 Inviable
s20 Paallysaho et al_2003 table1 Drosophila_littoralis_Drosophila_virilis Drosophila Drosophila_littoralis Drosophila_virilis Drosophila_littoralis_Drosophila_virilis Yes sound PI 41.2000000 4.9600000 19.4000000 2.9000000 19.7000000 1.2500000 10 10 10 10 10 0.451619923 Inviable
s20 Paallysaho et al_2003 table1 Drosophila_littoralis_Drosophila_virilis Drosophila Drosophila_littoralis Drosophila_virilis Drosophila_littoralis_Drosophila_virilis Yes sound IPI 286.0000000 51.5000000 39.4000000 2.3200000 19.7000000 1.2500000 10 10 10 10 10 3.435973249 Inviable
s20 Paallysaho et al_2003 table1 Drosophila_flavomontana_Drosophila_virilis Drosophila Drosophila_flavomontana Drosophila_virilis Drosophila_flavomontana_Drosophila_virilis Yes sound PI 27.1000000 2.3800000 22.9000000 2.1800000 17.5000000 2.0700000 19.7000000 1.2500000 10 10 10 10 10 10 10 10 -0.193605661 Viable
s20 Paallysaho et al_2003 table1 Drosophila_flavomontana_Drosophila_virilis Drosophila Drosophila_flavomontana Drosophila_virilis Drosophila_flavomontana_Drosophila_virilis Yes sound IPI 113.0000000 8.9300000 42.6000000 5.2100000 29.5000000 2.2200000 19.7000000 1.2500000 10 10 10 10 10 10 10 10 2.005673474 Viable
s20 Paallysaho et al_2003 table1 Drosophila_flavomontana_Drosophila_montana Drosophila Drosophila_flavomontana Drosophila_montana Drosophila_flavomontana_Drosophila_montana Yes sound pause 85.7000000 9.9400000 39.0000000 8.8800000 15.0000000 2.2100000 10 10 10 8 10 1.999563908 Inviable
s20 Paallysaho et al_2003 table1 Drosophila_flavomontana_Drosophila_montana Drosophila Drosophila_flavomontana Drosophila_montana Drosophila_flavomontana_Drosophila_montana Yes sound PI 27.1000000 2.3800000 16.6000000 0.9200000 20.7000000 2.7100000 10 10 10 8 10 -0.269872170 Inviable
s20 Paallysaho et al_2003 table1 Drosophila_flavomontana_Drosophila_montana Drosophila Drosophila_flavomontana Drosophila_montana Drosophila_flavomontana_Drosophila_montana Yes sound IPI 113.0000000 8.9300000 55.6000000 9.0200000 35.7000000 2.1100000 10 10 10 8 10 1.089934291 Inviable
s20 Paallysaho et al_2003 table1 Drosophila_flavomontana_Drosophila_littoralis Drosophila Drosophila_flavomontana Drosophila_littoralis Drosophila_flavomontana_Drosophila_littoralis Yes sound pause 85.7000000 9.9400000 128.0000000 19.1000000 245.0000000 52.4000000 10 10 10 5 10 0.933086029 Inviable
s20 Paallysaho et al_2003 table1 Drosophila_flavomontana_Drosophila_littoralis Drosophila Drosophila_flavomontana Drosophila_littoralis Drosophila_flavomontana_Drosophila_littoralis Yes sound PI 27.1000000 2.3800000 20.8000000 0.8400000 41.2000000 4.9600000 10 10 10 5 10 -0.039595049 Inviable
s20 Paallysaho et al_2003 table1 Drosophila_flavomontana_Drosophila_littoralis Drosophila Drosophila_flavomontana Drosophila_littoralis Drosophila_flavomontana_Drosophila_littoralis Yes sound IPI 113.0000000 8.9300000 148.0000000 19.1000000 286.0000000 51.5000000 10 10 10 5 10 0.745479142 Inviable
s22 Shaw_1996 table4 KW L. paranigra Laupala Laupala_kohalensis Laupala_paranigra Laupala_kohalensis_Laupala_paranigra Yes sound Pulse period 0.2710000 0.0100000 0.4640000 0.0140000 0.5960000 0.0150000 1.4230000 0.1500000 40 40 5 5 2 2 28 28 40 5 2 28 1.869566995 Viable
s22 Shaw_1996 table4 KW L. paranigra Laupala Laupala_kohalensis Laupala_paranigra Laupala_kohalensis_Laupala_paranigra Yes sound Pulse rate 3.6940000 0.1320000 2.1590000 0.0670000 1.6780000 0.0420000 0.7180000 0.0790000 40 40 5 5 2 2 28 28 40 5 2 28 1.838132903 Viable
s22 Shaw_1996 table4 KW L. paranigra Laupala Laupala_kohalensis Laupala_paranigra Laupala_kohalensis_Laupala_paranigra Yes sound Carrier frequency 4.9270000 0.2460000 5.2930000 0.3040000 5.2930000 0.3040000 5.1180000 0.1990000 38 38 5 5 2 2 27 27 38 5 2 27 -0.626238889 Viable
s22 Shaw_1996 table4 KW L. paranigra Laupala Laupala_kohalensis Laupala_paranigra Laupala_kohalensis_Laupala_paranigra Yes sound Pulse duration 39.7700000 4.4100000 38.4000000 2.3300000 38.7600000 0.3400000 38.3700000 4.5300000 37 37 5 5 2 2 27 27 37 5 2 27 -0.629622089 Viable
s22 Shaw_1996 table4 OF L. paranigra Laupala Laupala_kohalensis Laupala_paranigra Laupala_kohalensis_Laupala_paranigra Yes sound Pulse period 0.2710000 0.0100000 0.5200000 0.0230000 0.5730000 0.0270000 1.0790000 0.0870000 40 40 10 10 4 4 27 27 40 10 4 27 1.443324350 Viable
s22 Shaw_1996 table4 OF L. paranigra Laupala Laupala_kohalensis Laupala_paranigra Laupala_kohalensis_Laupala_paranigra Yes sound Pulse rate 3.6940000 0.1320000 1.9250000 0.0860000 1.7480000 0.0800000 0.9330000 0.0780000 40 40 10 10 4 4 27 27 40 10 4 27 1.434681617 Viable
s22 Shaw_1996 table4 OF L. paranigra Laupala Laupala_kohalensis Laupala_paranigra Laupala_kohalensis_Laupala_paranigra Yes sound Carrier frequency 4.9270000 0.2460000 4.9940000 0.0960000 5.0190000 0.2450000 5.0810000 0.2330000 38 38 10 10 4 4 25 25 38 10 4 25 -0.637414533 Viable
s22 Shaw_1996 table4 OF L. paranigra Laupala Laupala_kohalensis Laupala_paranigra Laupala_kohalensis_Laupala_paranigra Yes sound Pulse duration 39.7700000 4.4100000 39.9600000 1.8500000 35.9400000 3.3600000 38.1700000 0.6000000 37 37 10 10 4 4 25 25 37 10 4 25 -0.621572586 Viable
s25 Suvanto et al_1994 table 1&2 Drosophila_lummei_Drosophila_virilis Drosophila Drosophila_lummei Drosophila_virilis Drosophila_lummei_Drosophila_virilis Yes sound inhbt_PL 9.0000000 3.5774006 10.0000000 3.1841727 11.0000000 8.3708755 11.0000000 3.7425055 5 5 4 5 105 104 87 112 -0.375733818 Viable
s25 Suvanto et al_1994 table 1&2 Drosophila_lummei_Drosophila_virilis Drosophila Drosophila_lummei Drosophila_virilis Drosophila_lummei_Drosophila_virilis Yes sound inhbt_CN 3.0000000 0.9937224 3.0000000 0.9950540 3.0000000 3.2666831 4.0000000 0.9848699 5 5 4 5 105 104 87 112 -0.241712907 Viable
s25 Suvanto et al_1994 table 1&2 Drosophila_lummei_Drosophila_virilis Drosophila Drosophila_lummei Drosophila_virilis Drosophila_lummei_Drosophila_virilis Yes sound inhbt_IPI 51.0000000 16.0983025 53.0000000 26.8664575 48.0000000 30.2168190 46.0000000 30.5309658 5 5 4 5 105 104 87 112 -0.525889171 Viable
s25 Suvanto et al_1994 table 1&2 Drosophila_borealis_Drosophila_virilis Drosophila Drosophila_borealis Drosophila_virilis Drosophila_borealis_Drosophila_virilis Yes sound inhbt_PL 8.0000000 9.6613487 12.0000000 5.9309256 12.0000000 8.4409717 11.0000000 3.7425055 4 4 2 5 96 86 51 112 -0.194316281 Viable
s25 Suvanto et al_1994 table 1&2 Drosophila_borealis_Drosophila_virilis Drosophila Drosophila_borealis Drosophila_virilis Drosophila_borealis_Drosophila_virilis Yes sound inhbt_CN 2.0000000 1.8115029 3.0000000 1.8406321 3.0000000 1.5549158 4.0000000 0.9848699 4 4 2 5 96 86 51 112 0.382812357 Viable
s25 Suvanto et al_1994 table 1&2 Drosophila_borealis_Drosophila_virilis Drosophila Drosophila_borealis Drosophila_virilis Drosophila_borealis_Drosophila_virilis Yes sound inhbt_IPI 28.0000000 57.9680922 34.0000000 61.5589175 30.0000000 60.4195866 46.0000000 30.5309658 4 4 2 5 96 86 51 112 0.079825624 Viable
s25 Suvanto et al_1994 table 1&2 Drosophila_littoralis_Drosophila_virilis Drosophila Drosophila_littoralis Drosophila_virilis Drosophila_littoralis_Drosophila_virilis Yes sound inhbt_PL 9.0000000 5.0099491 11.0000000 4.9521372 11.0000000 3.7425055 5 4 5 99 81 112 -0.375733818 Inviable
s25 Suvanto et al_1994 table 1&2 Drosophila_littoralis_Drosophila_virilis Drosophila Drosophila_littoralis Drosophila_virilis Drosophila_littoralis_Drosophila_virilis Yes sound inhbt_CN 2.0000000 1.0019898 3.0000000 1.2380343 4.0000000 0.9848699 5 4 5 99 81 112 0.382812357 Inviable
s25 Suvanto et al_1994 table 1&2 Drosophila_littoralis_Drosophila_virilis Drosophila Drosophila_littoralis Drosophila_virilis Drosophila_littoralis_Drosophila_virilis Yes sound inhbt_IPI 62.0000000 40.6807864 34.0000000 35.4903165 46.0000000 30.5309658 5 4 5 99 81 112 -0.225061190 Inviable
s25 Suvanto et al_1994 table 1&2 Drosophila_montana_Drosophila_virilis Drosophila Drosophila_montana Drosophila_virilis Drosophila_montana_Drosophila_virilis Yes sound inhbt_PL 12.0000000 41.0676782 13.0000000 8.4855081 11.0000000 3.7425055 5 5 5 114 131 112 -0.550799722 Inviable
s25 Suvanto et al_1994 table 1&2 Drosophila_montana_Drosophila_virilis Drosophila Drosophila_montana Drosophila_virilis Drosophila_montana_Drosophila_virilis Yes sound inhbt_CN 3.0000000 4.9124017 4.0000000 1.3499672 4.0000000 0.9848699 5 5 5 114 131 112 -0.241712907 Inviable
s25 Suvanto et al_1994 table 1&2 Drosophila_montana_Drosophila_virilis Drosophila Drosophila_montana Drosophila_virilis Drosophila_montana_Drosophila_virilis Yes sound inhbt_IPI 21.0000000 21.8110635 35.0000000 20.8280654 46.0000000 30.5309658 5 5 5 114 131 112 0.522933350 Inviable
s25 Suvanto et al_1994 table 1&2 Drosophila_kanekoi_Drosophila_virilis Drosophila Drosophila_kanekoi Drosophila_virilis Drosophila_kanekoi_Drosophila_virilis Yes sound inhbt_PL 25.0000000 17.1493686 11.0000000 3.5013480 11.0000000 3.7425055 4 3 5 28 82 112 0.579710113 Inviable
s25 Suvanto et al_1994 table 1&2 Drosophila_kanekoi_Drosophila_virilis Drosophila Drosophila_kanekoi Drosophila_virilis Drosophila_kanekoi_Drosophila_virilis Yes sound inhbt_CN 5.0000000 3.7281236 4.0000000 1.0298082 4.0000000 0.9848699 4 3 5 28 82 112 -0.341119579 Inviable
s25 Suvanto et al_1994 table 1&2 Drosophila_kanekoi_Drosophila_virilis Drosophila Drosophila_kanekoi Drosophila_virilis Drosophila_kanekoi_Drosophila_virilis Yes sound inhbt_IPI 218.0000000 92.2089242 36.0000000 23.6855892 46.0000000 30.5309658 4 3 5 28 82 112 1.711612257 Inviable
s25 Suvanto et al_1994 table 1&2 Drosophila_flavomontana_Drosophila_lacicola Drosophila Drosophila_flavomontana Drosophila_lacicola Drosophila_flavomontana_Drosophila_lacicola Yes sound inhbt_PL 13.0000000 6.8200006 12.0000000 3.9527756 11.0000000 4.6213692 5 5 5 187 158 72 -0.427512435 Inviable
s25 Suvanto et al_1994 table 1&2 Drosophila_flavomontana_Drosophila_lacicola Drosophila Drosophila_flavomontana Drosophila_lacicola Drosophila_flavomontana_Drosophila_lacicola Yes sound inhbt_CN 3.0000000 1.1059460 3.0000000 0.9411370 3.0000000 1.0503112 5 5 5 187 158 72 -0.684820633 Inviable
s25 Suvanto et al_1994 table 1&2 Drosophila_flavomontana_Drosophila_lacicola Drosophila Drosophila_flavomontana Drosophila_lacicola Drosophila_flavomontana_Drosophila_lacicola Yes sound inhbt_IPI 31.0000000 15.8518933 35.0000000 15.0581927 62.0000000 38.0212646 5 5 5 187 158 72 0.382812357 Inviable
s26 Tomaru&Oguma_1994 table1 A541.auraria_B16.biauraria Drosophila Drosophila_auraria Drosophila_biauraria Drosophila_auraria_Drosophila_biauraria Yes sound IPI 21.4000000 1.9000000 15.7000000 0.5200000 16.0000000 0.5000000 12.9000000 0.9100000 6 6 10~20 10~20 10~20 10~20 10 10 6 22 15 10 180 220 150 300 0.094807394 Viable
s26 Tomaru&Oguma_1994 table1 A541.auraria_B18.biauraria Drosophila Drosophila_auraria Drosophila_biauraria Drosophila_auraria_Drosophila_biauraria Yes sound IPI 21.4000000 1.9000000 15.2000000 1.3100000 16.2000000 0.4200000 12.4000000 0.7600000 6 6 10~20 10~20 6 10~20 9 9 6 12 6 9 180 120 60 270 0.155695512 Viable
s26 Tomaru&Oguma_1994 table1 A662.auraria_B18.biauraria Drosophila Drosophila_auraria Drosophila_biauraria Drosophila_auraria_Drosophila_biauraria Yes sound IPI 18.9000000 1.9800000 16.6000000 0.3700000 15.8000000 0.4900000 12.4000000 0.7600000 8 8 5 5 6 6 9 9 8 5 6 9 240 50 60 270 -0.035650543 Viable
s26 Tomaru&Oguma_1994 table1 sn.cn.ba2.auraria_B16.biauraria Drosophila Drosophila_auraria Drosophila_biauraria Drosophila_auraria_Drosophila_biauraria Yes sound IPI 19.9000000 0.7200000 16.3000000 0.6000000 12.9000000 0.9100000 10~20 10~20 10 10 11 27 10 110 270 300 -0.017125774 Inviable
s26 Tomaru&Oguma_1994 table1 A541.auraria_T544_triauraria Drosophila Drosophila_auraria Drosophila_triauraria Drosophila_auraria_Drosophila_triauraria Yes sound IPI 21.4000000 1.9000000 17.3000000 0.4300000 18.1000000 0.3900000 16.1000000 0.9600000 6 6 8 8 10 10 7 7 6 8 10 7 180 80 100 210 -0.246503794 Viable
s26 Tomaru&Oguma_1994 table1 A541.auraria_quadraria Drosophila Drosophila_auraria Drosophila_quadraria Drosophila_auraria_Drosophila_quadraria Yes sound IPI 21.4000000 1.9000000 17.1000000 0.4100000 17.6000000 0.2600000 15.6000000 0.6800000 6 6 9 9 6 6 5 5 6 9 6 5 180 90 60 150 -0.197910842 Viable
s26 Tomaru&Oguma_1994 table1 A541.auraria_subauraria Drosophila Drosophila_auraria Drosophila_subauraria Drosophila_auraria_Drosophila_subauraria Yes sound IPI 21.4000000 1.9000000 14.3000000 0.4000000 11.1000000 0.6400000 6 6 3 3 10 10 6 3 10 180 30 258 0.326282386 Inviable
s26 Tomaru&Oguma_1994 table1 Drosophila_triauraria_Drosophila_quadraria Drosophila Drosophila_triauraria Drosophila_quadraria Drosophila_triauraria_Drosophila_quadraria Yes sound IPI 16.1000000 0.9600000 14.9000000 0.3700000 16.5000000 0.5900000 15.6000000 0.6800000 7 7 9 9 6 6 5 5 210 9 6 150 -0.636227681 Viable
s26 Tomaru&Oguma_1994 table1 Drosophila_triauraria_Drosophila_biauraria Drosophila Drosophila_triauraria Drosophila_biauraria Drosophila_triauraria_Drosophila_biauraria Yes sound IPI 16.1000000 0.9600000 14.3000000 0.6000000 12.9000000 0.9100000 7 7 6 6 10 10 210 60 300 -0.343509445 Inviable
s26 Tomaru&Oguma_1994 table1 Drosophila_quadraria_Drosophila_biauraria Drosophila Drosophila_quadraria Drosophila_biauraria Drosophila_quadraria_Drosophila_biauraria Yes sound IPI 11.1000000 0.6400000 13.4000000 0.2700000 13.9000000 0.2800000 12.9000000 0.9100000 5 5 10 10 5 5 10 10 150 10 5 300 -0.453345642 Viable
s26 Tomaru&Oguma_1994 table1 Drosophila_quadraria_Drosophila_subauraria Drosophila Drosophila_quadraria Drosophila_subauraria Drosophila_quadraria_Drosophila_subauraria Yes sound IPI 11.1000000 0.6400000 13.3000000 0.5200000 11.1000000 0.6400000 5 5 10~20 10~20 10 10 150 140 258 -0.684820633 Inviable
s26 Tomaru&Oguma_1994 table1 Drosophila_biauraria_Drosophila_subauraria Drosophila Drosophila_biauraria Drosophila_subauraria Drosophila_biauraria_Drosophila_subauraria Yes sound IPI 12.9000000 0.9100000 11.8000000 0.3600000 11.5000000 0.5100000 11.1000000 0.6400000 10 10 8 8 8 8 10 10 300 8 8 258 -0.453345642 Viable
s27 Wells_1994 table1 Chrysoperla_johnsoni_Chrysoperla_plorabunda Chrysoperla Chrysoperla_johnsoni Chrysoperla_plorabunda Chrysoperla_johnsoni_Chrysoperla_plorabunda Yes sound Initial Volley frequency 71.3000000 4.9193496 1.100 82.2000000 4.4090815 0.900 79.3000000 2.5000000 0.500 75.1000000 7.6733304 1.6000 10 10 10 10 10 10 10 10 20 24 25 23 -0.604843358 Viable
s27 Wells_1994 table1 Chrysoperla_johnsoni_Chrysoperla_plorabunda Chrysoperla Chrysoperla_johnsoni Chrysoperla_plorabunda Chrysoperla_johnsoni_Chrysoperla_plorabunda Yes sound Middle Volley frequency 58.2000000 2.2360680 0.500 67.9000000 2.9393877 0.600 64.3000000 3.5000000 0.700 59.1000000 3.3570821 0.7000 10 10 10 10 10 10 10 10 20 24 25 23 -0.661184331 Viable
s27 Wells_1994 table1 Chrysoperla_johnsoni_Chrysoperla_plorabunda Chrysoperla Chrysoperla_johnsoni Chrysoperla_plorabunda Chrysoperla_johnsoni_Chrysoperla_plorabunda Yes sound End Volley frequency 46.2000000 4.0249224 0.900 43.5000000 6.3686733 1.300 37.3000000 5.5000000 1.100 40.3000000 3.3570821 0.7000 10 10 10 10 10 10 10 10 20 24 25 23 -0.474376278 Viable
s27 Wells_1994 table1 Chrysoperla_johnsoni_Chrysoperla_plorabunda Chrysoperla Chrysoperla_johnsoni Chrysoperla_plorabunda Chrysoperla_johnsoni_Chrysoperla_plorabunda Yes sound I-E Volley frequency 25.1000000 7.6026311 1.700 38.7000000 7.3484692 1.500 41.9000000 4.5000000 0.900 34.7000000 8.6324967 1.8000 10 10 10 10 10 10 10 10 20 24 25 23 -0.185970935 Viable
s27 Wells_1994 table1 Chrysoperla_johnsoni_Chrysoperla_plorabunda Chrysoperla Chrysoperla_johnsoni Chrysoperla_plorabunda Chrysoperla_johnsoni_Chrysoperla_plorabunda Yes sound Volley duration 1586.0000000 652.9318494 146.000 892.0000000 274.3428512 56.000 718.0000000 170.0000000 34.000 604.0000000 105.5082935 22.0000 10 10 10 10 10 10 10 10 20 24 25 23 0.802149039 Viable
s27 Wells_1994 table1 Chrysoperla_johnsoni_Chrysoperla_plorabunda Chrysoperla Chrysoperla_johnsoni Chrysoperla_plorabunda Chrysoperla_johnsoni_Chrysoperla_plorabunda Yes sound Volley interval 3499.0000000 1350.5850584 302.000 2220.0000000 357.6255024 73.000 1938.0000000 335.0000000 67.000 1199.0000000 153.4666087 32.0000 10 10 10 10 10 10 10 10 20 24 25 23 0.964790849 Viable
s28 Shaw_2000 table1 KW L. paranigra Laupala Laupala_kohalensis Laupala_paranigra Laupala_kohalensis_Laupala_paranigra Yes sound Pulse duration 3.7500000 0.1400000 2.2200000 0.0700000 1.8800000 0.1200000 0.9400000 0.0500000 8 8 4 4 10 4 2 10 1.446343429 Viable
s28 Shaw_2000 table1 SB L. paranigra Laupala Laupala_kohalensis Laupala_paranigra Laupala_kohalensis_Laupala_paranigra Yes sound Pulse duration 3.7500000 0.1400000 2.4300000 0.0700000 2.0900000 0.1200000 1.0500000 0.0700000 8 8 4 4 10 2 2 10 1.275888706 Viable
s29 Sasabe_et.al_2007 fig2+text Carabus_iwawakianus_Carabus_maiyasanus Carabus Carabus_iwawakianus Carabus_maiyasanus Carabus_iwawakianus_Carabus_maiyasanus Yes morphology CPL 1.2740000 0.0650000 1.7780000 0.1470000 1.8940000 0.1120000 2.5360000 0.1410000 13 13 33 33 33 26 96 22 0.375541208 Viable
s29 Sasabe_et.al_2007 fig2+text Carabus_iwawakianus_Carabus_maiyasanus Carabus Carabus_iwawakianus Carabus_maiyasanus Carabus_iwawakianus_Carabus_maiyasanus Yes morphology CPW 0.7530000 0.0360000 0.4820000 0.0400000 0.4300000 0.0450000 0.3600000 0.0200000 13 13 33 33 33 26 96 22 0.451837988 Viable

Study.ID: ID of studies

Study.name: Including author name(s) and published year

Source: Source of phenotypc data in the primary studes

Cross.ID: Parental species used in the crossing expreiments. Distinguishes intraspecific populations.

Gennus: Studied genus

sp1.name and sp2.name: Crossed species. Ordered alphabetically.

species.pair: Parental species used in the crossing expreiments. Not distinguiscr intraspecific populations.

homologous: Measured traits are homologous across all crosses. If not, data has been excluded

trait.type: Sound or Morphology. Used in regressions bellow as a moderator.

trait: Trait name described in primary studies

Mn.~: Phenotypic mean of each cross

SD.~: SD of phenotype in each cross

SE.~: SE of phenotype in each cross

Parents.~: Number of parents used in each crossing. Usually not provided by the primary studies.

N.~: Number of individuals whose phenotype was measured

reps.~: Number of measurements, if replicated (especially in behavioral traits). Not used in the analyses bellow.

Pheno.divergence: Phenotypic divergence between parents in the focal trait, which is calculated as absolute value of log response ratio (lnRR) of phenotypic means. Used in regressions bellow as a moderator.

The species-level moderator dataset of this study.

meta <- read.xlsx(
    "../data/original.data.xlsx", sheet = "Species.level.moderators"
    # Same data is also saved as "../data/original.data.Species.level.moderators.txt"
    ) %>%
  mutate_at(vars(contains("divergence")), as.numeric) %>%
  # Logalize genetic divergence
  mutate_at(vars(contains("divergence")), log10)

# making a scrollable table
kable(meta, "html") %>% kable_styling("striped", position = "left") %>% 
    scroll_box(width = "100%", height = "500px")
sp1.name sp2.name species.pair Cross.ID Distribution Source_distribution taxa souce_sex.determinaton sex.determination Hetero.sex Genet.divergence Survival.sp1 Survival.hyb12 Survival.hyb21 Survival.sp2 surv.relat.hyb12 surv.relat.hyb21 surv.File surv.Source surv.Study.name comments parentals
Drosophila_auraria Drosophila_biauraria Drosophila_auraria_Drosophila_biauraria A541.auraria_B16.biauraria Overlap original study Diptera Vicoso Beatriz and Doris Bachtrog. “Numerous transitions of sex chromosomes in Diptera.” PLoS biology 13.4 (2015): e1002078. XY Male -1.4814861 NA NA parental data provided in other paper (Tomaru.Oguma_1993.AnimBehav)_N: n of song_Parents: n of indv (mass culture)
Drosophila_auraria Drosophila_biauraria Drosophila_auraria_Drosophila_biauraria A541.auraria_B18.biauraria Overlap original study Diptera Vicoso Beatriz and Doris Bachtrog. “Numerous transitions of sex chromosomes in Diptera.” PLoS biology 13.4 (2015): e1002078. XY Male -1.4814861 NA NA parental data provided in other paper (Tomaru.Oguma_1993.AnimBehav)_N: n of song_Parents: n of indv (mass culture)
Drosophila_auraria Drosophila_quadraria Drosophila_auraria_Drosophila_quadraria A541.auraria_quadraria Allopatry original study Diptera Vicoso Beatriz and Doris Bachtrog. “Numerous transitions of sex chromosomes in Diptera.” PLoS biology 13.4 (2015): e1002078. XY Male -3.0000000 NA NA
Drosophila_auraria Drosophila_subauraria Drosophila_auraria_Drosophila_subauraria A541.auraria_subauraria Allopatry original study Diptera Vicoso Beatriz and Doris Bachtrog. “Numerous transitions of sex chromosomes in Diptera.” PLoS biology 13.4 (2015): e1002078. XY Male -1.4814861 NA NA
Drosophila_auraria Drosophila_triauraria Drosophila_auraria_Drosophila_triauraria A541.auraria_T544_triauraria Overlap original study Diptera Vicoso Beatriz and Doris Bachtrog. “Numerous transitions of sex chromosomes in Diptera.” PLoS biology 13.4 (2015): e1002078. XY Male -2.6989700 NA NA
Drosophila_auraria Drosophila_biauraria Drosophila_auraria_Drosophila_biauraria A662.auraria_B18.biauraria Overlap original study Diptera Vicoso Beatriz and Doris Bachtrog. “Numerous transitions of sex chromosomes in Diptera.” PLoS biology 13.4 (2015): e1002078. XY Male -1.4814861 NA NA parental data provided in other paper (Tomaru.Oguma_1993.AnimBehav)_N: n of song_Parents: n of indv (mass culture)
Agrotis_ipsilon Agrotis_segetum Agrotis_ipsilon_Agrotis_segetum Agrotis_ipsilon_Agrotis_segetum Overlap original study Lepidoptera Traut W. K. Sahara and F. Marec. “Sex chromosomes and sex determination in Lepidoptera.” Sexual Development 1.6 (2007): 332-346. ZW/Z0 Female -1.3098039 65 1 0 60 -4.1351665567423561 NA Gadenne_PheromoneReceptor_JChemEcol.1997 table1 Gadenne et al_1997
Drosophila_melanogaster Drosophila_simulans Drosophila_melanogaster_Drosophila_simulans Basc Allopatry original study Diptera Vicoso Beatriz and Doris Bachtrog. “Numerous transitions of sex chromosomes in Diptera.” PLoS biology 13.4 (2015): e1002078. XY Male -1.2924298 1 0.5 0.2 1 -0.69314718055994529 -1.6094379124341003 reviewed in Sawamura_
Drosophila_mauritiana Drosophila_simulans Drosophila_mauritiana_Drosophila_simulans BGxMutant Allopatry original study Diptera Vicoso Beatriz and Doris Bachtrog. “Numerous transitions of sex chromosomes in Diptera.” PLoS biology 13.4 (2015): e1002078. XY Male -1.7212464 NA NA
Drosophila_mauritiana Drosophila_simulans Drosophila_mauritiana_Drosophila_simulans BGxOxnard Allopatry original study Diptera Vicoso Beatriz and Doris Bachtrog. “Numerous transitions of sex chromosomes in Diptera.” PLoS biology 13.4 (2015): e1002078. XY Male -1.7212464 NA NA
Drosophila_mauritiana Drosophila_simulans Drosophila_mauritiana_Drosophila_simulans BGxSPD(wildtype) Allopatry original study Diptera Vicoso Beatriz and Doris Bachtrog. “Numerous transitions of sex chromosomes in Diptera.” PLoS biology 13.4 (2015): e1002078. XY Male -1.7212464 NA NA
Carabus_iwawakianus Carabus_maiyasanus Carabus_iwawakianus_Carabus_maiyasanus Carabus_iwawakianus_Carabus_maiyasanus Overlap original study Coleoptera Serrano J. and J. S. Yadav. “Chromosome numbers and sex-determining mechanisms in adephagan Coleoptera.” The Coleopterists’ Bulletin (1984): 335-357. XY Male -1.8538720
Drosophila_madeirensis Drosophila_subobscura Drosophila_madeirensis_Drosophila_subobscura chcu Allopatry original study Diptera Vicoso Beatriz and Doris Bachtrog. “Numerous transitions of sex chromosomes in Diptera.” PLoS biology 13.4 (2015): e1002078. XY Male 0.5435714 NA NA
Chorthippus_biguttulus Chorthippus_brunneus Chorthippus_biguttulus_Chorthippus_brunneus Chorthippus_biguttulus_Chorthippus_brunneus Overlap original study Orthoptera Castillo Elio Rodrigo Dardo Andrea Marti and Claudio Juan Bidau. “Sex and neo-sex chromosomes in Orthoptera: a review.” Journal of Orthoptera Research (2010): 213-231. X0/XY Male -0.0710923 0.59322033898305082 0.5 0.72368421052631582 0.35294117647058826 5.5341989352007639E-2 0.42508901485809281 Perdeck_1958_Grasshopper table7 wild but caught in juvenile stage
Chrysoperla_johnsoni Chrysoperla_plorabunda Chrysoperla_johnsoni_Chrysoperla_plorabunda Chrysoperla_johnsoni_Chrysoperla_plorabunda Overlap original study Neuroptera Tauber Catherine A. and Maurice J. Tauber. “Inheritance of seasonal cycles in Chrysoperla (Insecta: Neuroptera).” Genetics Research 49.3 (1987): 215-223. XY Male -1.9586073 0.62551999999999996 0.45435714285714285 0.489375 0.54733333333333334 -0.25516407769093707 -0.1809185580094152 Wells_1993_Lacewings table1
Drosophila_biauraria Drosophila_subauraria Drosophila_biauraria_Drosophila_subauraria Drosophila_biauraria_Drosophila_subauraria Allopatry original study Diptera Vicoso Beatriz and Doris Bachtrog. “Numerous transitions of sex chromosomes in Diptera.” PLoS biology 13.4 (2015): e1002078. XY Male -1.9586073 NA NA
Drosophila_borealis Drosophila_virilis Drosophila_borealis_Drosophila_virilis Drosophila_borealis_Drosophila_virilis Allopatry original study Diptera Vicoso Beatriz and Doris Bachtrog. “Numerous transitions of sex chromosomes in Diptera.” PLoS biology 13.4 (2015): e1002078. XY Male -0.9208188 0.99 NA NA Parents: ?? (mass culture)_SD estimated by Wan et al 2014
Drosophila_buzzatii Drosophila_koepferae Drosophila_buzzatii_Drosophila_koepferae Drosophila_buzzatii_Drosophila_koepferae Overlap original study Diptera Vicoso Beatriz and Doris Bachtrog. “Numerous transitions of sex chromosomes in Diptera.” PLoS biology 13.4 (2015): e1002078. XY Male 0.0224284 NA NA
Drosophila_flavomontana Drosophila_lacicola Drosophila_flavomontana_Drosophila_lacicola Drosophila_flavomontana_Drosophila_lacicola Allopatry original study Diptera Vicoso Beatriz and Doris Bachtrog. “Numerous transitions of sex chromosomes in Diptera.” PLoS biology 13.4 (2015): e1002078. XY Male 0.0047512 NA NA Parents: ?? (mass culture)_SD estimated by Wan et al 2014
Drosophila_flavomontana Drosophila_littoralis Drosophila_flavomontana_Drosophila_littoralis Drosophila_flavomontana_Drosophila_littoralis Allopatry original paper Diptera Vicoso Beatriz and Doris Bachtrog. “Numerous transitions of sex chromosomes in Diptera.” PLoS biology 13.4 (2015): e1002078. XY Male -0.1938200 NA NA
Drosophila_flavomontana Drosophila_montana Drosophila_flavomontana_Drosophila_montana Drosophila_flavomontana_Drosophila_montana Allopatry original paper Diptera Vicoso Beatriz and Doris Bachtrog. “Numerous transitions of sex chromosomes in Diptera.” PLoS biology 13.4 (2015): e1002078. XY Male 0.1048284 NA NA
Drosophila_flavomontana Drosophila_virilis Drosophila_flavomontana_Drosophila_virilis Drosophila_flavomontana_Drosophila_virilis Allopatry original study Diptera Vicoso Beatriz and Doris Bachtrog. “Numerous transitions of sex chromosomes in Diptera.” PLoS biology 13.4 (2015): e1002078. XY Male 0.0132587 0.99 NA NA
Drosophila_heteroneura Drosophila_silvestris Drosophila_heteroneura_Drosophila_silvestris Drosophila_heteroneura_Drosophila_silvestris Overlap “Drosophila heteroneura and Drosophila silvestris: Head Shapes, Behavior and Evolution” Diptera Vicoso Beatriz and Doris Bachtrog. “Numerous transitions of sex chromosomes in Diptera.” PLoS biology 13.4 (2015): e1002078. XY Male -2.0457575 NA NA
Drosophila_kanekoi Drosophila_virilis Drosophila_kanekoi_Drosophila_virilis Drosophila_kanekoi_Drosophila_virilis Allopatry original study Diptera Vicoso Beatriz and Doris Bachtrog. “Numerous transitions of sex chromosomes in Diptera.” PLoS biology 13.4 (2015): e1002078. XY Male -0.9507820 0.99 NA NA Parents: ?? (mass culture)_SD estimated by Wan et al 2014
Drosophila_littoralis Drosophila_virilis Drosophila_littoralis_Drosophila_virilis Drosophila_littoralis_Drosophila_virilis Allopatry original study Diptera Vicoso Beatriz and Doris Bachtrog. “Numerous transitions of sex chromosomes in Diptera.” PLoS biology 13.4 (2015): e1002078. XY Male -0.9136402 0.95499999999999996 0 0.16 0.99 0 -1.8046962602587744 Orr_Coyne_1989_Drosophila fertility_table2&3
Drosophila_lummei Drosophila_virilis Drosophila_lummei_Drosophila_virilis Drosophila_lummei_Drosophila_virilis Allopatry original study Diptera Vicoso Beatriz and Doris Bachtrog. “Numerous transitions of sex chromosomes in Diptera.” PLoS biology 13.4 (2015): e1002078. XY Male -1.2441251 0.97499999999999998 0.98 0.95 0.99 -2.5477720787986644E-3 -3.3638359148829802E-2 Orr_Coyne_1989_Drosophila fertility_table2&3 Parents: ?? (mass culture)_SD estimated by Wan et al 2014
Drosophila_montana Drosophila_virilis Drosophila_montana_Drosophila_virilis Drosophila_montana_Drosophila_virilis Allopatry original study Diptera Vicoso Beatriz and Doris Bachtrog. “Numerous transitions of sex chromosomes in Diptera.” PLoS biology 13.4 (2015): e1002078. XY Male -1.0457575 0.99 NA NA
Drosophila_persimilis Drosophila_pseudoobscura Drosophila_persimilis_Drosophila_pseudoobscura Drosophila_persimilis_Drosophila_pseudoobscura Overlap original study Diptera Vicoso Beatriz and Doris Bachtrog. “Numerous transitions of sex chromosomes in Diptera.” PLoS biology 13.4 (2015): e1002078. XY Male -2.2218487 NA NA
Drosophila_quadraria Drosophila_biauraria Drosophila_quadraria_Drosophila_biauraria Drosophila_quadraria_Drosophila_biauraria Allopatry original study Diptera Vicoso Beatriz and Doris Bachtrog. “Numerous transitions of sex chromosomes in Diptera.” PLoS biology 13.4 (2015): e1002078. XY Male -2.3979400 NA NA
Drosophila_quadraria Drosophila_subauraria Drosophila_quadraria_Drosophila_subauraria Drosophila_quadraria_Drosophila_subauraria Allopatry original study Diptera Vicoso Beatriz and Doris Bachtrog. “Numerous transitions of sex chromosomes in Diptera.” PLoS biology 13.4 (2015): e1002078. XY Male -1.4814861 NA NA
Drosophila_triauraria Drosophila_biauraria Drosophila_triauraria_Drosophila_biauraria Drosophila_triauraria_Drosophila_biauraria Allopatry original study Diptera Vicoso Beatriz and Doris Bachtrog. “Numerous transitions of sex chromosomes in Diptera.” PLoS biology 13.4 (2015): e1002078. XY Male -1.4814861 NA NA
Drosophila_triauraria Drosophila_quadraria Drosophila_triauraria_Drosophila_quadraria Drosophila_triauraria_Drosophila_quadraria Allopatry original study Diptera Vicoso Beatriz and Doris Bachtrog. “Numerous transitions of sex chromosomes in Diptera.” PLoS biology 13.4 (2015): e1002078. XY Male -3.0000000 NA NA
Coturnix_coturnix_coturnix Coturnix_japonica Coturnix_coturnix_coturnix_Coturnix_japonica Coturnix_coturnix_coturnix_Coturnix_japonica Allopatry original study Aves Ezaz Tariq et al. “Relationships between vertebrate ZW and XY sex chromosome systems.” Current Biology 16.17 (2006): R736-R743. ZW Female -1.7447275 0.347634 0.38592000000000004 0.32175000000000004 0.10447989191213911 -7.7375355710390822E-2 Deregnaucourt_2002_Quail table2&3
Drosophila_sechellia Drosophila_simulans Drosophila_sechellia_Drosophila_simulans f^2 Allopatry original study Diptera Vicoso Beatriz and Doris Bachtrog. “Numerous transitions of sex chromosomes in Diptera.” PLoS biology 13.4 (2015): e1002078. XY Male -1.3872161 NA_possibly_high NA_possibly_high NA_possibly_high NA_possibly_high NA NA
Drosophila_sechellia Drosophila_simulans Drosophila_sechellia_Drosophila_simulans FC Allopatry original study Diptera Vicoso Beatriz and Doris Bachtrog. “Numerous transitions of sex chromosomes in Diptera.” PLoS biology 13.4 (2015): e1002078. XY Male -1.3872161 NA_possibly_high NA_possibly_high NA_possibly_high NA_possibly_high NA NA
Gryllus_armatus Gryllus_rubens Gryllus_armatus_Gryllus_rubens Gryllus_armatus_Gryllus_rubens Allopatry original paper Orthoptera Castillo Elio Rodrigo Dardo Andrea Marti and Claudio Juan Bidau. “Sex and neo-sex chromosomes in Orthoptera: a review.” Journal of Orthoptera Research (2010): 213-231. X0 Male NA NA N of indv_N of songs. N of parental pairs: 12
Gryllus_campestris Gryllus_rubens Gryllus_campestris_Gryllus_rubens Gryllus_campestris_Gryllus_rubens Allopatry original paper Orthoptera Castillo Elio Rodrigo Dardo Andrea Marti and Claudio Juan Bidau. “Sex and neo-sex chromosomes in Orthoptera: a review.” Journal of Orthoptera Research (2010): 213-231. X0 Male 0.6626634 NA NA N of indv_N of songs. N of parental pairs: 12
Gryllus_rubens Gryllus_texensis Gryllus_rubens_Gryllus_texensis Gryllus_rubens_Gryllus_texensis Overlap original study Orthoptera Castillo Elio Rodrigo Dardo Andrea Marti and Claudio Juan Bidau. “Sex and neo-sex chromosomes in Orthoptera: a review.” Journal of Orthoptera Research (2010): 213-231. X0 Male -2.0457575 76.5 69.099999999999994 52.4 43.8 0.13871328835293623 -0.13793485109369141 Cade_1989_Gryllus.mortality table1 integerはtexensis
Drosophila_madeirensis Drosophila_subobscura Drosophila_madeirensis_Drosophila_subobscura H27 Allopatry original study Diptera Vicoso Beatriz and Doris Bachtrog. “Numerous transitions of sex chromosomes in Diptera.” PLoS biology 13.4 (2015): e1002078. XY Male 0.5435714 NA NA
Haplochromis_burtoni Haplochromis_nubilus Haplochromis_burtoni_Haplochromis_nubilus Haplochromis_burtoni_Haplochromis_nubilus Allopatry original study Cichliformes 0 NA NA
Hyla_chrysoscelis Hyla_femoralis Hyla_chrysoscelis_Hyla_femoralis Hyla_chrysoscelis_Hyla_femoralis Overlap original study Anura Miura I. “The late replication banding patterns of chromosomes are highly conserved in the genera Rana Hyla and Bufo (Amphibia: Anura).” Chromosoma 103.8 (1995): 567-574. XY Male -0.0070049 NA NA
Laupala_kohalensis Laupala_paranigra Laupala_kohalensis_Laupala_paranigra KW L. paranigra Allopatry original study Orthoptera Castillo Elio Rodrigo Dardo Andrea Marti and Claudio Juan Bidau. “Sex and neo-sex chromosomes in Orthoptera: a review.” Journal of Orthoptera Research (2010): 213-231. X0 Male NA NA
Drosophila_madeirensis Drosophila_subobscura Drosophila_madeirensis_Drosophila_subobscura mad Overlap original study Diptera Vicoso Beatriz and Doris Bachtrog. “Numerous transitions of sex chromosomes in Diptera.” PLoS biology 13.4 (2015): e1002078. XY Male 0.5435714 NA NA
Drosophila_madeirensis Drosophila_subobscura Drosophila_madeirensis_Drosophila_subobscura Mdh86 Allopatry original study Diptera Vicoso Beatriz and Doris Bachtrog. “Numerous transitions of sex chromosomes in Diptera.” PLoS biology 13.4 (2015): e1002078. XY Male 0.5435714 NA NA
Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus musculus.1 Allopatry original study Rodentia Ezaz Tariq et al. “Relationships between vertebrate ZW and XY sex chromosome systems.” Current Biology 16.17 (2006): R736-R743. XY Male -1.5376020 NA NA N of indv_genetic distance_first 20 sequences were used_respectively
Mus_musculus_domesticus Mus_musculus_musculus Mus_musculus_domesticus_Mus_musculus_musculus musculus.3 Allopatry original study Rodentia Ezaz Tariq et al. “Relationships between vertebrate ZW and XY sex chromosome systems.” Current Biology 16.17 (2006): R736-R743. XY Male -1.5376020 NA NA N of indv_genetic distance_first 20 sequences were used_respectively
Laupala_kohalensis Laupala_paranigra Laupala_kohalensis_Laupala_paranigra OF L. paranigra Allopatry original study Orthoptera Castillo Elio Rodrigo Dardo Andrea Marti and Claudio Juan Bidau. “Sex and neo-sex chromosomes in Orthoptera: a review.” Journal of Orthoptera Research (2010): 213-231. X0 Male NA NA
Drosophila_sechellia Drosophila_simulans Drosophila_sechellia_Drosophila_simulans Oxnard Allopatry original study Diptera Vicoso Beatriz and Doris Bachtrog. “Numerous transitions of sex chromosomes in Diptera.” PLoS biology 13.4 (2015): e1002078. XY Male -1.3872161 NA_possibly_high NA_possibly_high NA_possibly_high NA_possibly_high NA NA
Chorthippus_parallelus_erythropus Chorthippus_parallelus_parallelus Chorthippus_parallelus_erythropus_Chorthippus_parallelus_parallelus parallelus_localityA Overlap original study Orthoptera Castillo Elio Rodrigo Dardo Andrea Marti and Claudio Juan Bidau. “Sex and neo-sex chromosomes in Orthoptera: a review.” Journal of Orthoptera Research (2010): 213-231. X0 Male NA NA
Chorthippus_parallelus_erythropus Chorthippus_parallelus_parallelus Chorthippus_parallelus_erythropus_Chorthippus_parallelus_parallelus parallelus_localityB Overlap original study Orthoptera Castillo Elio Rodrigo Dardo Andrea Marti and Claudio Juan Bidau. “Sex and neo-sex chromosomes in Orthoptera: a review.” Journal of Orthoptera Research (2010): 213-231. X0 Male NA NA
Drosophila_mauritiana Drosophila_sechellia Drosophila_mauritiana_Drosophila_sechellia pn_j_irX85 Allopatry original study Diptera Vicoso Beatriz and Doris Bachtrog. “Numerous transitions of sex chromosomes in Diptera.” PLoS biology 13.4 (2015): e1002078. XY Male -1.4814861 0 NA NA
Pundamilia_nyererei Pundamilia_pundamilia Pundamilia_nyererei_Pundamilia_pundamilia Pundamilia_nyererei_Pundamilia_pundamilia Overlap original study Cichliformes 4.8600000000000003 4.84 4.51 4.57 2.616580464311944E-2 -4.445176257083381E-2 Van Der Sluijs_2008_Cichlid text
Drosophila_sechellia Drosophila_simulans Drosophila_sechellia_Drosophila_simulans RM Allopatry original study Diptera Vicoso Beatriz and Doris Bachtrog. “Numerous transitions of sex chromosomes in Diptera.” PLoS biology 13.4 (2015): e1002078. XY Male -1.3872161 NA_possibly_high NA_possibly_high NA_possibly_high NA_possibly_high NA NA
Drosophila_sechellia Drosophila_simulans Drosophila_sechellia_Drosophila_simulans RMdet Allopatry original study Diptera Vicoso Beatriz and Doris Bachtrog. “Numerous transitions of sex chromosomes in Diptera.” PLoS biology 13.4 (2015): e1002078. XY Male -1.3872161 NA_possibly_high NA_possibly_high NA_possibly_high NA_possibly_high NA NA
Laupala_kohalensis Laupala_paranigra Laupala_kohalensis_Laupala_paranigra SB L. paranigra Allopatry original study Orthoptera Castillo Elio Rodrigo Dardo Andrea Marti and Claudio Juan Bidau. “Sex and neo-sex chromosomes in Orthoptera: a review.” Journal of Orthoptera Research (2010): 213-231. X0/XY Male NA NA
Drosophila_auraria Drosophila_biauraria Drosophila_auraria_Drosophila_biauraria sn.cn.ba2.auraria_B16.biauraria Overlap original study Diptera Vicoso Beatriz and Doris Bachtrog. “Numerous transitions of sex chromosomes in Diptera.” PLoS biology 13.4 (2015): e1002078. XY Male -1.4814861 NA NA parental data provided in other paper (Tomaru.Oguma_1993.AnimBehav)_N: n of song_Parents: n of indv (mass culture)
Spodoptera_descoinsi Spodoptera_latifascia Spodoptera_descoinsi_Spodoptera_latifascia Spodoptera_descoinsi_Spodoptera_latifascia Overlap original paper Lepidoptera Traut W. K. Sahara and F. Marec. “Sex chromosomes and sex determination in Lepidoptera.” Sexual Development 1.6 (2007): 332-346. ZW/Z0 Female -1.4685211 NA NA
Teleogryllus_commodus Teleogryllus_oceanicus Teleogryllus_commodus_Teleogryllus_oceanicus Teleogryllus_commodus_Teleogryllus_oceanicus Overlap The Australian crickets (Orthoptera: Gryllidae) Orthoptera Castillo Elio Rodrigo Dardo Andrea Marti and Claudio Juan Bidau. “Sex and neo-sex chromosomes in Orthoptera: a review.” Journal of Orthoptera Research (2010): 213-231. X0 Male 0.1182647 NA NA N of indv_N of songs. N of parental pairs: 12
Drosophila_melanogaster Drosophila_simulans Drosophila_melanogaster_Drosophila_simulans v Allopatry original study Diptera Vicoso Beatriz and Doris Bachtrog. “Numerous transitions of sex chromosomes in Diptera.” PLoS biology 13.4 (2015): e1002078. XY Male -1.2924298 1 0.5 0.2 1 -0.69314718055994529 -1.6094379124341003 reviewed in Sawamura_
Drosophila_melanogaster Drosophila_simulans Drosophila_melanogaster_Drosophila_simulans XsimYmel Allopatry original study Diptera Vicoso Beatriz and Doris Bachtrog. “Numerous transitions of sex chromosomes in Diptera.” PLoS biology 13.4 (2015): e1002078. XY Male -1.2924298 1 0.5 0.2 1 -0.69314718055994529 -1.6094379124341003 reviewed in Sawamura_
Drosophila_sechellia Drosophila_simulans Drosophila_sechellia_Drosophila_simulans XXY Allopatry original study Diptera Vicoso Beatriz and Doris Bachtrog. “Numerous transitions of sex chromosomes in Diptera.” PLoS biology 13.4 (2015): e1002078. XY Male -1.3872161 NA_possibly_high NA_possibly_high NA_possibly_high NA_possibly_high NA NA
#++++++++++++++++++++++++++++++++++++++++++++++
# Combine phenotypic data and moderators data
#++++++++++++++++++++++++++++++++++++++++++++++
original.dat <- left_join(pheno, meta)
# add unique ID for each effect size (row)
original.dat$ES.ID <- paste("ES",sprintf("%03d",c(1:dim(original.dat)[1])), sep="")

# #+++++++++++++++++++++++++++++++++
# print("Scaling")
# #+++++++++++++++++++++++++++++++++
# print("Phenotypic divergence ratio")
# attributes(pheno$Pheno.divergence)
# print("Minimum scaled value")
# min(pheno$Pheno.divergence)
# print("Maximum scaled value")
# max(pheno$Pheno.divergence)

Reciprocal: Viability of reciprocal hybrids, with two levels - Viable or Inviable

Genet.divergence: Natural logarithm of genetic distance at mtDNA COI region (>450bp).

Distribution: Distribution overlap - Allopatry or Overlap

Hetero.sex: Heterogametic sex - Female (ZW and Z0) or Male (XY and X0)

Species composition

#+++++++++++++++++++++#
# Phylogeny
#+++++++++++++++++++++#

# species pairs data 
taxa <- meta %>%
  select(-Cross.ID) %>%
  distinct_all(.keep_all = TRUE) %>%
  mutate_at("taxa", as.factor)

# matching names from open tree taxonomy
order <- tnrs_match_names(
  names = levels(taxa$taxa) %>%
    str_replace_all("_", " "), 
  context_name = "Animals"
  )

# which names return more than 1 match?
multimatch <- order$ott_id[order$number_matches != 1]
# inspect(order, ott_id = multimatch[1]) # Anura, confirmed adopted ott_id is correct
# inspect(order, ott_id = multimatch[2]) # Neuroptera, confirmed adopted ott_id is correct

# Create taxonomic tree
tree <- tol_induced_subtree(ott_ids = order$ott_id)
# Remove ott ids from tip label
tree$tip.label %<>%
  strip_ott_ids(remove_underscores=TRUE)
tree$tip.label[8] <- "Anura"

# # N of species pairs at each order
# factor(meta.sum$taxa, levels = as.vector(tree$tip.label))

plot.phylo <- ggtree(tree) + 
  geom_tiplab(
    geom = "image",
    image = paste("../data/pic", tree$tip.label, "png", sep = "."), 
    size = 0.1, offset = 3, hjust = 1
    ) +
  geom_tiplab(
    geom = "text",  
    label = tree$tip.label, 
    align = 1, size = 3
    ) +
  xlim(NA, 7)

# images from phylopic #    
# Lepidoptera (genus Catocala) "c224abfd-ee39-4923-98e5-c2606dcc56cb", 
# Diptera (Drosophila) "0cd6cc9f-683c-470e-a4a6-3b68beb826fa"
# Orthoptera (cricket) "b80d830b-155a-4ca5-9119-9a9fde019cc6"
# Rodentia (mouse), drawn by David Liao "0f6af3d8-49d2-4d75-8edf-08598387afde"
# Aves (Quail) "42f85a2b-7517-439a-8dc3-b745a35c035d"
# Anura (genus Hyla) "A22D353D-B045-4044-9432-8F340B9A3104", 
# Cichliformes (Nile tilapia), drawn by Milton Tan "84c7e672-2593-44a6-a807-cffbd3156cc5" 


#+++++++++++++++++++++#
# Summary 
#+++++++++++++++++++++#

summary <- original.dat %>%
  group_by(taxa) %>%
  summarise(
    'Species pair' = length(unique(species.pair)),
    'Obser- vation' = length(unique(ES.ID)),
    Study = length(unique(Study.ID))
    ) %>%
  # Order taxon so that match with phylogenetic tree topology
  within(taxa <- ordered(taxa, levels = c("Neuroptera", "Coleoptera", "Diptera", "Lepidoptera", "Orthoptera", "Aves", "Rodentia", "Anura", "Cichliformes")))


## Table ###
summary %>%
  summarise_if(is.numeric, sum) %>%
    mutate(taxa = "Total") %>%
  bind_rows(summary, .) %>%
  kable("html", digits = 3) %>% 
  kable_styling("striped", position = "left")
taxa Species pair Obser- vation Study
Anura 1 5 1
Aves 1 1 1
Cichliformes 2 6 3
Coleoptera 1 2 1
Diptera 23 65 9
Lepidoptera 2 13 2
Neuroptera 1 6 1
Orthoptera 7 63 6
Rodentia 1 240 1
Total 39 401 25
## Plot ###
plot.sum <- ggplot(
  # Make tidy summary data
  summary %>%
  gather(key = metrics, value = N, -c(taxa)) %>%
  # Order metrics
  within(
    metrics <- ordered(
      metrics,
      levels = c("Study", "Species pair", "Obser- vation")
      )
    ), 
  aes(x = "", y = N, fill = taxa)) +
  geom_bar(width = 1, stat = "identity") +
  scale_fill_brewer(palette = "Paired") +
  facet_wrap(
    scale = "free", "metrics",
    # strip text into two lines
    labeller = label_wrap_gen(width = 8)
    ) +
  xlab("") +
  stackedbartheme +
  theme(
    strip.text = element_text(size = 15),
    axis.text.y = element_text(size = 14)
    )

#+++++++++++++++++#
# Combine figures
#+++++++++++++++++#
# plot.all <- plot.phylo + plot.sum
plot.sum

# save(
#   plot = plot.all, 
#   file = "../Analysis/data.svg", height = 5, width = 8.5
#   )

Figure 1a

Taxonomic distribution of species-level moderator status

Summarised distributions of categorical species-level moderators in each taxon (order).

metavars <- c("Reciprocal", "Distribution", "Hetero.sex")

meta.unique <- original.dat %>%
  distinct_at("species.pair", .keep_all = TRUE) %>%
  mutate_at(metavars, as.factor)

meta.all.sp <- meta.unique %>% 
  group_by(taxa) %>%
  summarise(Total = length(species.pair)) 

for (i in metavars) {
  
  bind_rows(
    # At each taxon
    meta.unique %>% 
      group_by_("taxa", i) %>%
      summarise(species = length(species.pair))
    ,
    # All taxon
    meta.unique %>% 
      group_by_(i) %>%
      summarise(species = length(unique(species.pair))) %>% 
      mutate(taxa = "Total")
    ) %>%
    ungroup %>%
    spread(key = i, value = "species") %>%
    mutate_all(~replace(., is.na(.), 0)) %>% # replace NA by 0
    as.data.frame %>%
    # All species pair at each taxon: summing columns
    mutate(Total = rowSums(.[2:(1+nlevels(meta.unique[, i]))])) %>%
    # Calc % of level 2 (i.e. male hetero, ...)
    mutate('%' = round(.[3]/Total*100, 1)) %>%
    rename(!!paste0(levels(meta.unique[, i])[2], "%") := "%") %>%
    # Table output
    kable("html", digits = 3, caption = i) %>% 
    kable_styling("striped", position = "left") %>%
    print()

}  
Reciprocal
taxa Inviable Viable Total Viable%
Anura 0 1 1 100.0
Aves 0 1 1 100.0
Cichliformes 1 1 2 50.0
Coleoptera 0 1 1 100.0
Diptera 11 12 23 52.2
Lepidoptera 1 1 2 50.0
Neuroptera 0 1 1 100.0
Orthoptera 2 5 7 71.4
Rodentia 1 0 1 0.0
Total 16 23 39 59.0
Distribution
taxa Allopatry Overlap Total Overlap%
Anura 0 1 1 100.0
Aves 1 0 1 0.0
Cichliformes 1 1 2 50.0
Coleoptera 0 1 1 100.0
Diptera 19 4 23 17.4
Lepidoptera 0 2 2 100.0
Neuroptera 0 1 1 100.0
Orthoptera 3 4 7 57.1
Rodentia 1 0 1 0.0
Total 25 14 39 35.9
Hetero.sex
taxa Female Male <NA> Total Male%
Anura 0 1 0 1 100.0
Aves 1 0 0 1 0.0
Cichliformes 0 0 2 0
Coleoptera 0 1 0 1 100.0
Diptera 0 23 0 23 100.0
Lepidoptera 2 0 0 2 0.0
Neuroptera 0 1 0 1 100.0
Orthoptera 0 7 0 7 100.0
Rodentia 0 1 0 1 100.0
Total 3 34 2 37 91.9

Data used in meta-regression (all metadata available)

full_join(
  # All species pair
  original.dat %>%
    select(c("taxa", "species.pair")) %>%
    distinct_all() %>%
    group_by(taxa) %>%
    summarise('All species' = length(species.pair)),
  # Species pair used in meta-regression
  original.dat %>%
    filter(!is.na(sex.determination), !is.na(Genet.divergence)) %>%
    select(c("taxa", "species.pair")) %>%
    distinct_all() %>%
    group_by(taxa) %>%
    summarise('Metadata available' = length(species.pair))
  ) %>%
  mutate_all(~replace(., is.na(.), 0)) %>% # replace NA by 0
  kable("html", caption = "Numbers of all species pairs, and species pairs used in meta-regression
") %>% 
  kable_styling("striped", position = "left")
Numbers of all species pairs, and species pairs used in meta-regression
taxa All species Metadata available
Anura 1 1
Aves 1 1
Cichliformes 2 0
Coleoptera 1 1
Diptera 23 23
Lepidoptera 2 2
Neuroptera 1 1
Orthoptera 7 4
Rodentia 1 1

Two fish and three orthoptera species-pairs were not used in meta-regression and Bayesian phylogenetic mixed models because of the lack of data for genetic distance or sex-determination system (fish, Haplochromis burtoni × H. nubilus and Pundamilia nyererei × P. pundamilia; orthoptera, Chorthippus parallelus erythropus × C. parallelus parallelus, Gryllus armatus × G. rubens and Laupala kohalensis × L. paranigra). We did not assign value of the heterogametic sex in cichlid fishes that undergo frequent evolutionary changes in sex-determination system Yoshida et al. 2011.

Data processing

Allign parental species according to trait values

Currently, dataset is composed of

‘species 1’ and ‘species 2,’ ordered alphabetically, and ‘hybrid12’ (sp1 mother & sp2 father) and ‘hybrid 21’ (sp2 mother & sp1 father)

To investigate paternal effect in hybrids using difference in mean trait value between reciprocal cross, it’s better to allign species with larger trait value (spLLM) and smaller value (spSSM) in each traits. Name of hybrids will be changed according to change in names of parental species (hybridLSM & hybridSLM).

#+++++++++++++++++++++++++++++++++++++++++++++++++#
# sp1 >= sp2 in phenotypic mean 
#+++++++++++++++++++++++++++++++++++++++++++++++++#
# extract
sp1sp2.mean <- original.dat %>%
  filter(Mn.sp1 >= Mn.sp2) # filtering according to mean trait value of parentals
# change column name from sp1 or sp2 -> spL or spS
names(sp1sp2.mean) <- gsub("1", "L", names(sp1sp2.mean))
names(sp1sp2.mean) <- gsub("2", "S", names(sp1sp2.mean))

#+++++++++++++++++++++++++++++++++++++++++++++++++#
# sp1 < sp2 in phenotypic mean 
#+++++++++++++++++++++++++++++++++++++++++++++++++#
# extract
sp2sp1.mean <- original.dat %>%
  filter(Mn.sp1 < Mn.sp2)
# change column name from sp1 or sp2 -> spS or spL
names(sp2sp1.mean) <- gsub("1", "S", names(sp2sp1.mean))
names(sp2sp1.mean) <- gsub("2", "L", names(sp2sp1.mean))

#+++++++++++++++++++++++++++++++++++++++++++++++++#
# combine dataset & sort by ES.ID 
#+++++++++++++++++++++++++++++++++++++++++++++++++#
bind_rows(sp1sp2.mean, sp2sp1.mean) %>%
  arrange(ES.ID) %>%
  write.csv("../data/dat.mean.csv", quote=F,row.names = F)

Data set created here, dat.mean.csv, is used in calculating effect sizes for analyses investigating phenotypic mean and novelty in phenotypic means.

Allign parental species according to phenotypic variation (CV)

To investigate paternal effect in hybrids using difference in coefficient of variation (CV) between reciprocal cross, it’s better to allign species with larger CV (spLLV) and smaller CV (spSSV) in each traits. Name of hybrids will be changed according to change in names of parental species (hybridLSV & hybridSLV).

#+++++++++++++++++++++++++++++++++++++++++++++++++#
# sp1 >= sp2 in phenotypic variation (CV)
#+++++++++++++++++++++++++++++++++++++++++++++++++#
# extract
sp1sp2.var <- original.dat %>%
  filter(SD.sp1/Mn.sp1 >= SD.sp2/Mn.sp2) # filtering according to CV of parentals
# change column name from sp1 or sp2 -> spL or spS
names(sp1sp2.var) <- gsub("1", "L", names(sp1sp2.var))
names(sp1sp2.var) <- gsub("2", "S", names(sp1sp2.var))

#+++++++++++++++++++++++++++++++++++++++++++++++++#
# sp1 < sp2 in phenotypic variation (CV)
#+++++++++++++++++++++++++++++++++++++++++++++++++#
# extract
sp2sp1.var <- original.dat %>%
  filter(SD.sp1/Mn.sp1 < SD.sp2/Mn.sp2)
# change column name from sp1 or sp2 -> spS or spL
names(sp2sp1.var) <- gsub("1", "S", names(sp2sp1.var))
names(sp2sp1.var) <- gsub("2", "L", names(sp2sp1.var))

#+++++++++++++++++++++++++++++++++++++++++++++++++#
# combine dataset & sort by ES.ID 
#+++++++++++++++++++++++++++++++++++++++++++++++++#
bind_rows(sp1sp2.var, sp2sp1.var) %>%
  arrange(ES.ID) %>%
  write.csv("../data/dat.CV.csv", quote=F,row.names = F)

Data set created here, dat.CV.csv, is used in calculating effect sizes for analyses investigating phenotypic variation and novelty in phenotypic variabilities.

Simultaneously judge novel phenotype and variability expression

We categorised phenotypic novelty (novel or non-novel) and relative phenotypic variability (CV) compared to parents (smaller, intermediate, larger) at each trait.

bind_rows(
  # Assess novel phenotype & variability expression in hyb12
  original.dat %>%
    drop_na(Mn.hyb12, SD.hyb12) %>%
    mutate(
      cross = "1x2",
      # Relative trait size
      relative.mean = ifelse(
        # Exceeding upper range
        Mn.hyb12 > Mn.sp1 & Mn.hyb12 > Mn.sp2,
        "Larger",
        ifelse(
          # Exceeding lower range
          Mn.hyb12 < Mn.sp1 & Mn.hyb12 < Mn.sp2,
          "Smaller",
          "Intermediate"
        )
      ),
      # Relative variability size
      relative.var = ifelse(
        # Exceeding upper range: 1
        SD.hyb12/Mn.hyb12 > SD.sp1/Mn.sp1 & 
          SD.hyb12/Mn.hyb12 > SD.sp2/Mn.sp2,
        "Larger",
        ifelse(
          # Exceeding lower range: "Smaller"
          SD.hyb12/Mn.hyb12 < SD.sp1/Mn.sp1 & 
            SD.hyb12/Mn.hyb12 < SD.sp2/Mn.sp2,
          "Smaller",
          "Intermediate"
        )
      )    
    ),
  # Assess novel phenotype & variability expression in hyb12
  original.dat %>%
    drop_na(Mn.hyb21, SD.hyb21) %>%
    mutate(
      cross = "2x1",
      # Relative trait size
      relative.mean = ifelse(
        # Exceeding upper range: 1
        Mn.hyb21 > Mn.sp1 & Mn.hyb21 > Mn.sp2,
        "Larger",
        ifelse(
          # Exceeding lower range: "Smaller"
          Mn.hyb21 < Mn.sp1 & Mn.hyb21 < Mn.sp2,
          "Smaller",
          "Intermediate"
        ) 
      ) ,
      # Relative variability size
      relative.var = ifelse(
        # Exceeding upper range: 1
        SD.hyb21/Mn.hyb21 > SD.sp1/Mn.sp1 & 
          SD.hyb21/Mn.hyb21 > SD.sp2/Mn.sp2,
        "Larger",
        ifelse(
          # Exceeding lower range: "Smaller"
          SD.hyb21/Mn.hyb21 < SD.sp1/Mn.sp1 & 
            SD.hyb21/Mn.hyb21 < SD.sp2/Mn.sp2,
          "Smaller",
          "Intermediate"
        )
      )    
    ) 
  ) %>%
  mutate(mean.novelty = ifelse(relative.mean == "Intermediate", "Nonnovel", "Novel")) %>%
  write.csv("../data/dat.novelty.csv", quote=F,row.names = F)

Data set created here, dat.novelty.csv, is used in investigating phenotypic variability of novel phenotype.

Meta-analysis for phenotypic mean

We created data subset according to taxon (all taxon or insect only) and novelty in phenotypic means (all traits or non-novel traits - trait size of hybrids does not exceed size range of parents). We conduct identical analyses for full data and data subsets, and checked robustness of our results.

Calculating effect sizes

To quantify phenotypic difference from spSSM to the other crosses, we calculated log response ratio (lnRR) from phenotypic mean of spSSM to those of the other crosses (hybLSM, hybSLM and spLLM).
Effecct size was calculated by using escalc function in metafor package

# load phenotypic data
dat <- read.csv("../data/dat.mean.csv", head = TRUE)

# Order by taxon
dat$taxa <- ordered(
  dat$taxa,
  levels = c("Neuroptera", "Coleoptera", "Diptera", "Lepidoptera", "Orthoptera", "Aves", "Rodentia", "Anura", "Cichliformes")
  )

## Difference between hybrids and smaller species (spS) ###
mean.dif <- foreach(
  cr = c("hybLS", "hybSL", "spL"), 
  .combine = `rbind`
  ) %do% {
    ## lnRR ###
    escalc(
      measure = "ROM",
      # N of hybrids
      n1i = dat[, paste("N", cr, sep = ".")],
      # N of parentals
      n2i = dat[, "N.spS"],
      # Mean of hybrids
      m1i = dat[, paste("Mn", cr, sep = ".")],
      # Mean of parentals
      m2i = dat[, "Mn.spS"],
      # SD of hybrids
      sd1i = dat[, paste("SD", cr, sep = ".")],
      # SD of parentals
      sd2i = dat[, "SD.spS"],
      data = dat
      ) %>%
      rename(lnRR.es = yi, lnRR.sv = vi) %>%
    # indicate type of hybrid
    mutate(cross = cr)
    } %>% 
  drop_na(lnRR.sv) %>%
  arrange(ES.ID) %>%
  left_join(., dat) 
  
# Dataset able to compare reciprocal crosses
write.csv(
  mean.dif %>%
    filter(Reciprocal == "Viable"), 
  "../data/mean.ES.general.csv", row.names = F
  )

Funnel plots

res <- rma(
  yi = lnRR.es, vi = lnRR.sv, 
  data = mean.dif, method="FE"
  )

## set up 2x2 array for plotting
par(mfrow=c(2,2))
 
## draw funnel plots
funnel(res, main="Standard Error", xlim = c(-2, 4))
funnel(res, yaxis="vi", main="Sampling Variance", xlim = c(-2, 4))
funnel(res, yaxis="seinv", main="Inverse Standard Error", xlim = c(-2, 4))
funnel(res, yaxis="vinv", main="Inverse Sampling Variance", xlim = c(-2, 4))

Check data

Checked effect sizes with extremely high/low standard error (SE > 1.2 | 1/SE > 140) and confirmed that those data were correctly imported.

outliers <- mean.dif %>%
  # vi (sampling variance) 
  mutate(SE = sqrt(lnRR.sv)) %>%
  arrange(desc(SE)) %>%
  filter(SE > 1.2 | 1/SE > 140) %>%
  select(ES.ID, Study.name, SE, cross, Reciprocal, trait, Cross.ID) %>%
  mutate_if(is.numeric, round, 3)

outliers %>%
  kable("html", digits = 3, caption = "Effect sizes with extremely high/low standard error (SE > 1.2 | 1/SE > 140)") %>% 
  kable_styling("striped", position = "left") %>%
  scroll_box(width = "100%", height = "500px")
Effect sizes with extremely high/low standard error (SE > 1.2 | 1/SE > 140)
ES.ID Study.name SE cross Reciprocal trait Cross.ID
ES320 Musolf et al_2015 21.535 spL Inviable Frequ Modulated Downsweep_FAC1_2 musculus.3
ES320 Musolf et al_2015 21.470 hybSL Inviable Frequ Modulated Downsweep_FAC1_2 musculus.3
ES253 Musolf et al_2015 14.218 hybLS Inviable Complex 2_FAC2_1 musculus.3
ES253 Musolf et al_2015 9.883 spL Inviable Complex 2_FAC2_1 musculus.3
ES147 Musolf et al_2015 6.075 spL Inviable U Shaped Inverted_FAC1_2 musculus.1
ES123 Musolf et al_2015 2.073 hybLS Inviable Complex 2_FAC2_1 musculus.1
ES367 Suvanto et al_1994 1.761 hybLS Viable inhbt_IPI Drosophila_borealis_Drosophila_virilis
ES371 Suvanto et al_1994 1.538 spL Inviable inhbt_PL Drosophila_montana_Drosophila_virilis
ES367 Suvanto et al_1994 1.375 hybSL Viable inhbt_IPI Drosophila_borealis_Drosophila_virilis
ES125 Musolf et al_2015 1.276 spL Inviable Complex 2_FAC1_4 musculus.1
ES123 Musolf et al_2015 1.231 spL Inviable Complex 2_FAC2_1 musculus.1
ES388 Tomaru&Oguma_1994 0.007 hybSL Inviable IPI Drosophila_triauraria_Drosophila_biauraria
ES389 Tomaru&Oguma_1994 0.006 spL Viable IPI Drosophila_quadraria_Drosophila_biauraria
ES055 Coyne.et.al_1991 0.006 hybSL Viable Tibia length pn_j_irX85
ES036 Coyne_1983 0.006 spL Inviable WL BGxMutant
ES039 Coyne_1983 0.006 hybLS Viable WL BGxSPD(wildtype)
ES036 Coyne_1983 0.006 hybLS Inviable WL BGxMutant
ES390 Tomaru&Oguma_1994 0.006 spL Inviable IPI Drosophila_quadraria_Drosophila_subauraria
ES039 Coyne_1983 0.006 hybSL Viable WL BGxSPD(wildtype)
ES039 Coyne_1983 0.006 spL Viable WL BGxSPD(wildtype)
ES388 Tomaru&Oguma_1994 0.006 spL Inviable IPI Drosophila_triauraria_Drosophila_biauraria
ES387 Tomaru&Oguma_1994 0.005 spL Viable IPI Drosophila_triauraria_Drosophila_quadraria
ES391 Tomaru&Oguma_1994 0.005 spL Viable IPI Drosophila_biauraria_Drosophila_subauraria
ES390 Tomaru&Oguma_1994 0.005 hybLS Inviable IPI Drosophila_quadraria_Drosophila_subauraria
Because those outliers did not affect meta-analytic model convergence, we did not exclude those data.

Judging novelty in phenotypic means

# load spLS files
dat <- read.csv("../data/dat.mean.csv", head = TRUE)

#+++++++++++++++++++++++++++++++++++++++++++++++++++++++#
# Difference between larger species (spL) and hybrids 
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++#

for (i in c("spL")) { # identify type of hybrids
  for (cr in c("hybLS", "hybSL")) { # identify type of parentals
    assign(
      paste(cr, i, sep = "_"),
        ## lnRR ###
        escalc(
          measure = "ROM",
          # N of hybrids
          n1i = dat[, paste("N", i, sep = ".")],
          # N of parentals
          n2i = dat[, paste("N", cr, sep = ".")],
          # Mean of hybrids
          m1i = dat[, paste("Mn", i, sep = ".")],
          # Mean of parentals
          m2i = dat[, paste("Mn", cr, sep = ".")],
          # SD of hybrids
          sd1i = dat[, paste("SD", i, sep = ".")],
          # SD of parentals
          sd2i = dat[, paste("SD", cr, sep = ".")],
          data = dat
          ) %>%
        rename(lnRR.es = yi, lnRR.sv = vi) %>%
        select(ES.ID, contains("lnRR")) %>%
        mutate(
          # direction of transgressve segregation - greater than parent
          direction = "+",
          # SE for logistic distribution, for the weighted binomial regression
          # SE = pi/sqrt(3*(n_e + n_c))
          SE = pi/sqrt(3*(
            dat[, paste("N", i, sep = ".")] + dat[, paste("N", cr, sep = ".")]
          ))
        )
    )
  }
}

#+++++++++++++++++++++++++++++++++++++++++++++++++++++++#
# Difference between hybrids and smaller species (spS)
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++#

for (i in c("hybLS", "hybSL")) { # identify type of hybrids
  for (cr in c("spS")) { # identify type of parentals
    assign(
      paste(i, cr, sep = "_"),
        ## lnRR ###
        escalc(
          measure = "ROM",
          # N of hybrids
          n1i = dat[, paste("N", i, sep = ".")],
          # N of parentals
          n2i = dat[, paste("N", cr, sep = ".")],
          # Mean of hybrids
          m1i = dat[, paste("Mn", i, sep = ".")],
          # Mean of parentals
          m2i = dat[, paste("Mn", cr, sep = ".")],
          # SD of hybrids
          sd1i = dat[, paste("SD", i, sep = ".")],
          # SD of parentals
          sd2i = dat[, paste("SD", cr, sep = ".")],
          data = dat
          ) %>%
          rename(lnRR.es = yi, lnRR.sv = vi) %>%
        select(ES.ID, contains("lnRR")) %>%
        mutate(
          # direction of transgressve segregation - smaller than parent
          direction = "-",
          # SE for logistic distribution, for the weighted binomial regression
          # SE = pi/sqrt(3*(n_e + n_c))
          SE = pi/sqrt(3*(
            dat[, paste("N", i, sep = ".")] + dat[, paste("N", cr, sep = ".")]
          ))
        )
    )
  }
}

#+++++++++++++++++++++++++++++++++++++++++++++++++++++++#
# Data output
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++#

bind_rows(
  ## Difference with mother species ###
  bind_rows(hybLS_spL, hybSL_spS) %>%
    mutate(parental = "Mother"),
  ## Difference with father species ###
  bind_rows(hybLS_spS, hybSL_spL) %>%
    mutate(parental = "Father")
  ) %>%
  drop_na(lnRR.sv) %>%
  left_join(., dat) %>%
  # Assign novel phenotype to 1, non-novel phenotype to 0 for each effect size
  mutate(Novelty = ifelse(lnRR.es < 0, 1, 0)) %>%
  ## Join with metadata ###
  left_join(
    ., read.xlsx("../data/original.data.xlsx", sheet = "Species.level.moderators")
    ) %>%
  mutate_at(vars(contains("divergence")), as.numeric) %>%
  mutate_at(vars(contains("divergence")), scale) %>%
  as.data.frame %>%
  select(-trait) %>%
  mutate_at("taxa", as.factor) %>%
  within(levels(Novelty) <- c("No", "Novel phenotypic means")) %>%
  within(
    taxa <- ordered(
      taxa,
      levels = c("Neuroptera", "Coleoptera", "Diptera", "Lepidoptera", "Orthoptera", "Aves", "Rodentia", "Anura", "Cichliformes")
      )
    ) %>%
  # Remove rows without any metadata
  drop_na(Hetero.sex, Pheno.divergence, trait.type, Genet.divergence) %>%
  # Insect or no
  mutate(
    insect = ifelse(taxa %in% c("Aves", "Rodentia", "Anura", "Cichliformes"), "no", "insect"),
  ) %>%
  write.csv("../data/mean.ES.Novelty.csv", row.names = F)

Reload data & Prepare phylogenetic tree

# Load effect sizes
mean.dif <- read.csv("../data/mean.ES.general.csv", head = TRUE) %>%
  # indicate dataset including novel phenotype
  mutate(data.type = "Alltraits")

# All trait observation irrespective of phenotypic novelty
All <- read.csv("../data/mean.ES.Novelty.csv", head = TRUE) %>%
  filter(lnRR.es < 0) %>%
  distinct(ES.ID)

# Trait observation of non-novel phenotypes
Nonovel <- read.csv("../data/mean.ES.general.csv", head = TRUE) %>%
  filter(!(ES.ID %in% All$ES.ID)) %>%
  # indicate dataset without novel phenotype
  mutate(data.type = "Nonnoveltraits")

# combine dataset with/without novel phenotype
Novel.Nonnovel <- bind_rows(mean.dif, Nonovel) %>%
  mutate(metaunit =  str_c(data.type, cross, sep = "_"))%>%
  # Use observations with both reciprocal crosses
  drop_na(contains("Mn"), contains("SD")) %>%
  # Insect or no
  mutate(
    insect = ifelse(taxa %in% c("Cichliformes", "Anura", "Aves", "Rodentia"), "no", "insect"),
  )


#+++++++++++++++++++++++++++++++++++++++++++++++#
# Phylogeny
#+++++++++++++++++++++++++++++++++++++++++++++++#

# # matching names from open tree taxonomy
# taxa <- tnrs_match_names(
#   names = levels(mean.dif$spL.name) %>%
#     str_replace_all("_", " "), 
#   context_name = "Animals"
#   )
# 
# # which names return more than 1 match?
# inspect(taxa, ott_id = taxa$ott_id[taxa$number_matches != 1])
# 
# # fixing names with more than 1 match
# taxa[taxa$number_matches != 1, ] <- 
#   inspect(taxa, ott_id = taxa$ott_id[taxa$number_matches != 1])[1, ]
# 
# tree <- tol_induced_subtree(ott_ids = taxa$ott_id)
# tree$tip.label %<>%
#   strip_ott_ids(remove_underscores=TRUE)
# 
# print("Original tree from OTL")
# plot(tree, no.margin=TRUE)
# 
# # randomly solve non-binary phylogeny
# set.seed(6)
# bin.tree <- multi2di(tree, random = T) 
# print("Randomly solved phylogeny")
# plot(bin.tree)
# 
# # correlation matrix to fit to the model
# bin.tree$tip.label <- bin.tree$tip.label %>%
#   as.factor() 
# 
# levels(bin.tree$tip.label) <- levels(mean.dif$spL.name) # making sure names match
# bin.tree$tip.label <- as.character(bin.tree$tip.label) # converting names back to character
# 
# write.tree(bin.tree, file= "../data/phylo.mean.tre")

# compute branch lengths of tree
phylo_branch <- read.tree(file = "../data/phylo.mean.tre") %>%
  compute.brlen(bin.tree, method = "Grafen", power = 1)

# saving phylogeneic matrix
phylo_cor <- vcv(phylo_branch, cor = T)

# Note one of the tips is called "Lates calcarifer (estimated)"
phylo_branch$node.label <- NULL

# Plot tree
plot.phylo(phylo_branch, cex = 0.7)
Figure S1. Phylogenetic tree used in meta-analysis for phenotypic mean, which was based on tree of the parental species with larger phenotypic mean

Figure S1. Phylogenetic tree used in meta-analysis for phenotypic mean, which was based on tree of the parental species with larger phenotypic mean


Phylogenetic tree created based on taxonomic tree on Open Tree of Life. Non-binary tree was randomly solved. We used packages rotl, ape and phytools on R.

Dominance in phenotypic means

Compare midparent and hybrids by comparing difference from spSSM phenotypic mean to midparent-value \(\frac{spLL_M+spSS_M}{2}\) and to hybrids’ phenotypic mean.

  • lnRR of midparent to spSSM: \(\ln\frac{spLL_M+spSS_M}{2spSS_M}\)
  • lnRR of hybrids to spSSM: \(\ln\frac{hybrid}{spSS_M}\)

As the variance of \(\ln\frac{spLL_M+spSS_M}{2spSS_M}\), we use the variance of \(\ln\frac{spLL_M}{spSS_M}\) for simplicity

We statistically compared those effect sizes through the formal meta-regression by using rma.mv function of R package metafor

All meta-analytic models included following Random effects estimates:

  • Study.ID: Primary studies. Denoted as Study

  • Cross.ID: Parental strain used in the crossing. Discriminate intraspecific populations. Denoted as crossed strain

  • spL.name: Phylogeny of parental species (spLLM). Denoted as species with phylogeny

#++++++++++++++++++++++++++++++++++++++++++++++++++++#
# Calculate midparent 
#++++++++++++++++++++++++++++++++++++++++++++++++++++#
midparent <- Novel.Nonnovel %>%
  # Divide mean by 2 in spL whereas hybrids are constant
  mutate(
    lnRR.midparent.es = 
      ifelse(
        cross == "spL",
        log(((Mn.spL + Mn.spS)/2)/Mn.spS), lnRR.es
        )
    # Divide variance by 4 in spL whereas hybrids are constant
    ) %>%
  mutate_at("cross", as.factor) %>%
  within(levels(cross) <- c("hybLS", "hybSL", "midparent"))


#+++++++++++++++++++++++++++++++++++++++++++++++++++#
# Compare midparent and hybrids by meta-regresson
#+++++++++++++++++++++++++++++++++++++++++++++++++++#
for (tr in c("Alltraits", "Nonnoveltraits")) {
  for (taxon in c("alltaxon", "insect")) {
    
    if (taxon == "alltaxon") {
      dat <- midparent %>% 
        filter(data.type == tr)
    } else {
      dat <- midparent %>% 
        filter(data.type == tr, insect == taxon)
    }
  
    # ## phylogenetic random regresson comparing with midparent ###
    # midparent.compare <- rma.mv(
    #   yi = lnRR.midparent.es,
    #   V = lnRR.sv,
    #   data = dat,
    #   method = "REML",
    #   random = list(~1 | spL.name, ~1 | Study.ID, ~1 | Cross.ID, ~1 | ES.ID),
    #   R = list(spL.name = phylo_cor),
    #   mods = ~ relevel(cross, ref = "midparent")
    #   )
    # ## Save model ###
    # saveRDS(
    #   midparent.compare,
    #   file = paste("../Analysis/Mean.midparent.compare", tr, taxon, "obj", sep = ".")
    #   )

    ## Load model ###
    midparent.compare <- readRDS(
      paste("../Analysis/Mean.midparent.compare", tr, taxon, "obj", sep = ".")
      )
    assign(
      paste("Dominance", tr, taxon, sep = "."),
      midparent.compare %>% 
        get_reg() %>%
        # Show dataset name
        within(Dataset <- c(paste(tr, taxon), rep("", length(.$Estimate)-1))) %>%
        # Rename fixed effects
        within('Fixed effects' <- c("", "midparent (intrcpt)", "hybLS", "hybSL")) %>%
        # Difference of each cross from midparent in %
        mutate('Comparison with midparent' = c(
          rep("", 2),
          paste(
            round(
            100*(exp(midparent.compare$beta[1]+midparent.compare$beta[2])            -exp(midparent.compare$beta[1])), # hybrid LS
            2),
            "% larger"
            ),
          paste(
            round(
            100*(exp(midparent.compare$beta[1]+midparent.compare$beta[3])-exp(midparent.compare$beta[1])), # hybrid SL
            2),
            "% larger"
            )
          ))
      )
    
    # ## Meta-analysis for midparent to plot band ###
    # midparent.random <- rma.mv(
    #   yi = lnRR.midparent.es,
    #   V = lnRR.sv,
    #   data = dat %>% filter(cross == "midparent"),
    #   method = "REML",
    #   random = list(~1 | spL.name, ~1 | Study.ID, ~1 | Cross.ID, ~1 | ES.ID),
    #   R = list(spL.name = phylo_cor)
    #   )
    # ## Save model ###
    # saveRDS(
    #   midparent.random,
    #   file = paste("../Analysis/Mean.midparent", tr, taxon, "obj", sep = ".")
    #   )

  }
}

bind_rows(
  Dominance.Alltraits.alltaxon, Dominance.Nonnoveltraits.alltaxon,
  Dominance.Alltraits.insect, Dominance.Nonnoveltraits.insect
  ) %>%
  kable("html", digits = 3, caption = "Table S3. Results of meta-analysis investigating dominance in phenotypic means using full dataset or data subsets") %>% 
  kable_styling("striped", position = "left") %>%
  scroll_box(width = "100%", height = "500px")
Table S3. Results of meta-analysis investigating dominance in phenotypic means using full dataset or data subsets
Dataset Fixed effects Estimate LowerCI UpperCI P I2[total] %I2[species with phylogeny] %I2[study] %I2[crossed strain] %I2[residual] significance Comparison with midparent
Alltraits alltaxon 99.7% 38.8% 1.1% 0% 59.8%
midparent (intrcpt) 0.578 0.266 0.890 0
hybLS -0.073 -0.079 -0.067 0
-12.53 % larger
hybSL -0.100 -0.106 -0.093 0
-16.9 % larger
Nonnoveltraits alltaxon 99.7% 34.9% 1.3% 0% 63.5%
midparent (intrcpt) 0.677 0.370 0.984 0
hybLS -0.142 -0.149 -0.134 0
-26 % larger
hybSL -0.189 -0.196 -0.181 0
-33.84 % larger
Alltraits insect 99.6% 0% 10% 0% 89.6%
midparent (intrcpt) 0.396 0.306 0.486 0
hybLS -0.073 -0.079 -0.066 0
-10.42 % larger
hybSL -0.100 -0.106 -0.094 0
-14.15 % larger
Nonnoveltraits insect 99.5% 0% 9.1% 0% 90.4%
midparent (intrcpt) 0.494 0.395 0.594 0
hybLS -0.142 -0.150 -0.134 0
-21.69 % larger
hybSL -0.190 -0.198 -0.182 0
-28.36 % larger

Univarate meta-analysis for each cross

Quantify and visualise overall trend of phenotypic mean of hybrids compared to parents
Meta-analysis was repeated for subset data - including only non-novel phenotypes, only insects, and non-novel phenotypes in insects
Meta-analysis was conducted by using rma.mv function in metafor package

*Confidential interval : thick line

*Prediction interval : thin line

cap <- data.frame(
  Description = c(
    "Orchard plot for full data \n(Alltraits alltaxon)", 
    "Orchard plot for subset data:\n Excluding vertebrates \n(Alltraits insect)",
    "Orchard plot for subset data:\n Including all taxon but excluding novel phenotype \n(Nonnoveltraits alltaxon)",
    "Orchard plot for subset data:\n Excluding vertebrates and novel phenotype\n (Nonnoveltraits insect)"
    )
  ) %>%
  mutate_all(as.character)
row.names(cap) <- c("Alltraits.alltaxon", "Alltraits.insect", 
             "Nonnoveltraits.alltaxon", "Nonnoveltraits.insect")

for (tr in c("Alltraits", "Nonnoveltraits")) {
  for (taxon in c("alltaxon", "insect")) {
    
    if (taxon == "alltaxon") {
      dat <- Novel.Nonnovel %>%
        filter(cross == cr, data.type == tr)
    } else {
      dat <- Novel.Nonnovel %>%
        filter(cross == cr, data.type == tr, insect == taxon)
    }
    
    res.ma <- foreach(
      cr = c("spL", "hybLS", "hybSL"), .combine = `rbind`
      ) %do% {
      # # Phylogenetic random meta-analysis
      # phyl.random <- rma.mv(
      #   yi = lnRR.es, V = lnRR.sv,
      #   data = dat, method = "REML",
      #   random = list(
      #     ~1 | spL.name, ~1 | Study.ID, ~1 | Cross.ID, ~1 | ES.ID
      #     ),
      #   R = list(spL.name = phylo_cor)
      #   )
      # saveRDS(phyl.random,
      #   file = paste("../Analysis/Mean.meta", tr, taxon, cr, "obj", sep = "."))

      # creating summary table of results
      readRDS(
        paste("../Analysis/Mean.meta", tr, taxon, cr, "obj", sep = ".")
        ) %>%
          get_pred() %>%
          as.data.frame() %>%
          mutate(
            N = length(dat$ES.ID),
            # I2 = I2(phyl.random)["I2_total"] %>% round(3),
            cross = cr # indicate cross (spL, hybLS, hybSL)
            ) %>% 
        as.data.frame() %>%
        within('Dataset' <- c(paste(tr, taxon), "", "")) %>%  # dataset name in first row
        return()
        }
    
    if (taxon == "alltaxon") {
      dat.plot <- Novel.Nonnovel %>% 
        filter(data.type == tr)
    } else {
      dat.plot <- Novel.Nonnovel %>% 
        filter(data.type == tr, insect == taxon)
    }

    # Bind result of all crosses at each dataset
    assign(
      paste("res.ma", tr, taxon, sep = "."),
      res.ma
    )
    
    ## Midparent estimate & CI ###
    midparent.ma.2 <- readRDS(
      paste("../Analysis/Mean.midparent", tr, taxon, "obj", sep = ".")
      ) %>% 
      # Prediction interval of midparent
      get_pred() %>%
      as.data.frame()
    
    # creating a forest plot
    plot.metamean <- ggplot(
      data = res.ma, 
      aes(x = tanh(Estimate), y = cross)
      ) +
      scale_y_discrete(expand = c(0, 1)) +
      scale_x_continuous(
        limits = c(-1, 1), 
        breaks = seq(-1, 1, by = 0.5)
        ) + 
      ## Midparent CI ###
      geom_rect(
        aes(
          xmin = tanh(midparent.ma.2$LowerCI),
          xmax = tanh(midparent.ma.2$UpperCI),
          ymin = -Inf, ymax = Inf
          ),
        fill="Grey 90"
        ) +
      ## Midparent estimate ###
      geom_vline(
        xintercept = tanh(midparent.ma.2$Estimate), colour = "grey20", 
        alpha = 0.3, size = 1
        ) +
      ## Orchard plot ###
      geom_quasirandom(
        data = dat.plot, 
        aes(x = tanh(lnRR.es), y = cross, size = 1/lnRR.sv, color = cross), 
        alpha = 0.2, GroupOnX = FALSE
        ) + 
      scale_color_manual(values = c("#DC267F", "#785EF0", "#FE6100")) +
      # Delete legend for colors
      guides(fill = "none", colour = "none") +
      # Confidential interval : thicker line
      geom_errorbarh(
        aes(xmin = tanh(LowerCI), xmax = tanh(UpperCI)), 
        height = 0, size = 1.2, alpha = 0.6
        ) + 
      # Prediction interval : thinner line
      geom_errorbarh(
        aes(xmin = tanh(lowerPR), xmax = tanh(upperPR)), 
        height = 0.1, size = 0.5, alpha = 0.6
        ) +
      geom_vline(xintercept = 0, linetype = 2, colour = "black", alpha = 0.3) +
      ## Estimate ###
      geom_point(size = 3, shape = 21, fill = "black") + 
      # ## I^2 ###
      # annotate(
      #   "text", x = -0.93, y = c(1.35, 2.35, 3.35),
      #   label = paste("italic(I^2)==", res.ma$I2), 
      #   parse = TRUE, hjust = "left", size = 5
      # ) + 
      ## N ###
      annotate(
        "text", x = -0.93, y = 3.85,
        label = paste("italic(N)==", length(dat.plot$ES.ID)/3), 
        parse = TRUE, hjust = "left", size = 5
      ) + 
      annotate(
        "text", x = -0.68, y = 3.85,
        label = "each", hjust = "left", size = 5
      ) + 
      ylab("") +
      xlab(expression(
        paste("hyperbolic tangent of lnRR from ", italic("spSS")), 
        parse = TRUE
        )) +
      ggtitle(cap[paste(tr, taxon,sep="."),]) +
      orchardtheme 

    print(plot.metamean)
  
    # ggsave(
    #   plot = plot.metamean,
    #   file = paste("../Analysis/mean.general.metamean", tr, taxon, "svg", sep = "."),
    #   height = 4, width = 5
    #   )
    
  }
}

bind_rows(
  res.ma.Alltraits.alltaxon, res.ma.Nonnoveltraits.alltaxon,
  res.ma.Alltraits.insect, res.ma.Nonnoveltraits.insect
  ) %>%
  as.data.frame() %>%
  # mutate_at(vars('Estimate':'%I2[residual]'), as.numeric) %>%
  # select(Dataset, cross, Estimate, UpperCI, LowerCI, contains("PR"), contains("I2")) %>%
  kable("html", digits = 3, caption = "Meta-analyses results of full dataset and data subsets") %>% 
  kable_styling("striped", position = "left") %>%
  scroll_box(width = "100%", height = "500px")
Meta-analyses results of full dataset and data subsets
Dataset Fixed effects Estimate LowerCI UpperCI lowerPR upperPR P I2[total] %I2[species with phylogeny] %I2[study] %I2[crossed strain] %I2[residual] significance N cross
Alltraits alltaxon intrcpt 0.837 0.411 1.263 -0.552 2.226 0.000 99.9% 28.2% 7.3% 0% 64.4%
0 spL
Alltraits alltaxon intrcpt 0.477 0.246 0.708 -0.428 1.383 0.000 99.7% 16.8% 2.2% 0% 80.7%
0 hybLS
Alltraits alltaxon intrcpt 0.425 0.178 0.672 -0.587 1.437 0.001 99.8% 14.9% 2.5% 0% 82.4%
0 hybSL
Nonnoveltraits alltaxon intrcpt 0.983 0.555 1.411 -0.425 2.391 0.000 99.9% 24.5% 16.1% 0% 59.3%
79 spL
Nonnoveltraits alltaxon intrcpt 0.482 0.257 0.708 -0.316 1.280 0.000 99.6% 21% 0% 0% 78.6%
79 hybLS
Nonnoveltraits alltaxon intrcpt 0.421 0.210 0.633 -0.299 1.142 0.000 99.4% 22.3% 4.2% 0% 73%
79 hybSL
Alltraits insect intrcpt 0.604 0.446 0.762 -0.486 1.693 0.000 99.9% 0% 12.3% 0% 87.6%
92 spL
Alltraits insect intrcpt 0.362 0.265 0.460 -0.411 1.135 0.000 99.6% 0% 3.8% 0% 95.9%
92 hybLS
Alltraits insect intrcpt 0.298 0.193 0.402 -0.583 1.178 0.000 99.7% 0% 2.1% 0% 97.6%
92 hybSL
Nonnoveltraits insect intrcpt 0.741 0.541 0.940 -0.384 1.866 0.000 99.8% 0% 23.3% 0% 76.6%
72 spL
Nonnoveltraits insect intrcpt 0.367 0.280 0.455 -0.271 1.005 0.000 99.4% 0% 2% 0% 97.4%
72 hybLS
Nonnoveltraits insect intrcpt 0.313 0.225 0.401 -0.243 0.869 0.000 99.2% 0% 9.4% 0% 89.8%
72 hybSL

Crossing direction effect in phenotypic means

We statistically compared lnRR from spSSM to the other crosses through the formal meta-regression by using rma.mv function of R package metafor.

Here we asked if lnRR of hybSLM was smaller/larger than that of hybLSM

If \(\ln\frac{hybridLS_M}{spSS_M}>\ln\frac{hybridSL_M}{spSS_M}\), hybridLSM has larger phenotypic mean than hybridSLM …maternal inheritance

for (tr in c("Alltraits", "Nonnoveltraits")) {
  for (taxon in c("alltaxon", "insect")) {
    
    if (taxon == "alltaxon") {
      dat <- Novel.Nonnovel %>% 
        filter(data.type == tr)
    } else {
      dat <- Novel.Nonnovel %>% 
        filter(data.type == tr, insect == taxon)
    }
  
    # #+++++++++++++++++++++++++++++++++++++++++++++#
    # # phylogenetic random regresson (ANOVA)
    # #+++++++++++++++++++++++++++++++++++++++++++++#
    # # Regress by lnRR of phenotypic difference between parentals
    # phyl.random.spL <- rma.mv(
    #   yi = lnRR.es, V = lnRR.sv,
    #   data = dat, method = "REML",
    #   random = list(~1 | spL.name, ~1 | Study.ID, ~1 | Cross.ID, ~1 | ES.ID),
    #   R = list(spL.name = phylo_cor),
    #   mods = ~ relevel(cross, ref = "spL")
    #   )
    # phyl.random.hybLS <- rma.mv(
    #   yi = lnRR.es, V = lnRR.sv,
    #   data = dat, method = "REML",
    #   random = list(~1 | spL.name, ~1 | Study.ID, ~1 | Cross.ID, ~1 | ES.ID),
    #   R = list(spL.name = phylo_cor),
    #   mods = ~ cross
    #   )
    # # Save model ###
    # saveRDS(
    #   phyl.random.spL,
    #   file = paste("../Analysis/Mean.compare.from.spL", tr, taxon, "obj", sep = ".")
    #   )
    # saveRDS(
    #   phyl.random.hybLS,
    #   file = paste("../Analysis/Mean.compare.from.hybLS", tr, taxon, "obj", sep = ".")
    #   )
    
    phyl.random.hybLS <- readRDS(
      paste("../Analysis/Mean.compare.from.hybLS", tr, taxon, "obj", sep = ".")
      ) 

    assign(
      paste("Reciprocal", tr, taxon, sep = "."),
      phyl.random.hybLS %>% 
        get_reg() %>%
        # Show dataset name
        within(Dataset <- c(paste(tr, taxon), rep("", length(.$Estimate)-1))) %>%
        # Rename fixed effects
        within('Fixed effects' <- c("", "hybLS (intrcpt)", "hybSL", "spLL")) %>%
        # Difference of each cross from midparent in %
        mutate('Comparison with hybridLS' = c(
          rep("", 2),
          paste(
            round(
              (exp(phyl.random.hybLS$beta[1]+phyl.random.hybLS$beta[2]) -
                 exp(phyl.random.hybLS$beta[1])
               )*100,
              2),
            "% larger"
            ), 
          ""
          )
        )
      )
  }
}

bind_rows(
  Reciprocal.Alltraits.alltaxon, Reciprocal.Nonnoveltraits.alltaxon,
  Reciprocal.Alltraits.insect, Reciprocal.Nonnoveltraits.insect
  ) %>%
  kable("html", digits = 3, caption = "Table S4. Results of meta-analysis investigating crossing direction effects in phenotypic means using full dataset or data subsets") %>% 
  kable_styling("striped", position = "left") %>%
  scroll_box(width = "100%", height = "500px")
Table S4. Results of meta-analysis investigating crossing direction effects in phenotypic means using full dataset or data subsets
Dataset Fixed effects Estimate LowerCI UpperCI P I2[total] %I2[species with phylogeny] %I2[study] %I2[crossed strain] %I2[residual] significance Comparison with hybridLS
Alltraits alltaxon 99.8% 39.1% 2.9% 0% 57.9%
hybLS (intrcpt) 0.566 0.193 0.939 0.003
hybSL -0.028 -0.035 -0.022 0.000
-4.94 % larger
spLL 0.240 0.233 0.246 0.000
Nonnoveltraits alltaxon 99.8% 35.7% 2.2% 0% 61.9%
hybLS (intrcpt) 0.589 0.223 0.954 0.002
hybSL -0.049 -0.057 -0.041 0.000
-8.67 % larger
spLL 0.368 0.360 0.376 0.000
Alltraits insect 99.7% 0% 11.9% 0% 87.8%
hybLS (intrcpt) 0.349 0.239 0.460 0.000
hybSL -0.029 -0.036 -0.022 0.000
-4.08 % larger
spLL 0.239 0.233 0.245 0.000
Nonnoveltraits insect 99.6% 0% 9.7% 0% 89.9%
hybLS (intrcpt) 0.365 0.246 0.484 0.000
hybSL -0.051 -0.059 -0.043 0.000
-7.12 % larger
spLL 0.368 0.361 0.376 0.000

Meta-analysis for phenotypic variation (coefficient of variation - CV)

We created data subset according to taxon (all taxon or insect only) and novelty in phenotypic variabilities (all traits or non-novel traits - trait variability [in terms of coefficient of variation] of hybrids does not exceed size range of parents). We conduct identical analyses for full data and data subsets, and checked robustness of our results.

Effect size calculation

We quantified relative phenotypic variability of hybrids and the parent with large variability (spLLV) to the parent with small variability (spSSV), by using [lnCVR] (https://besjournals.onlinelibrary.wiley.com/doi/full/10.1111/2041-210X.12309) (Nakagawa et al. (2015)). We controlled mean-variance relationship by using Coefficient of Variation (CV) as the proxy of phenotypic variability.
Effecct size was calculated by using escalc function in metafor package

# load spLS files
dat <- read.csv("../data/dat.CV.csv", head = TRUE)

# Order by taxon
dat$taxa <- ordered(
  dat$taxa,
  levels = c("Neuroptera", "Coleoptera", "Diptera", "Lepidoptera", "Orthoptera", "Aves", "Rodentia", "Anura", "Cichliformes")
  )

var.dif <- foreach(
  cr = c("hybLS", "hybSL", "spL"), 
  .combine = `rbind`
  ) %do% {
    escalc(
      measure = "CVR",
      # N of hybrids
      n1i = dat[, paste("N", cr, sep = ".")],
      # N of parentals
      n2i = dat[, "N.spS"],
      # Mean of hybrids
      m1i = dat[, paste("Mn", cr, sep = ".")],
      # Mean of parentals
      m2i = dat[, "Mn.spS"],
      # SD of hybrids
      sd1i = dat[, paste("SD", cr, sep = ".")],
      # SD of parentals
      sd2i = dat[, "SD.spS"],
      data = dat
      ) %>%
    rename(lnCVR.es = yi, lnCVR.sv = vi) %>%
    mutate(cross = cr)
  } %>% 
  drop_na(lnCVR.es) %>%
  arrange(ES.ID) %>%
  left_join(., dat)

Funnel plots

res <- rma(yi = lnCVR.es, vi = lnCVR.sv, data = var.dif, method="FE")

## set up 2x2 array for plotting
par(mfrow=c(2,2))
## draw funnel plots
funnel(res, main="Standard Error", xlim = c(-5, 5))
funnel(res, yaxis="vi", main="Sampling Variance", xlim = c(-5, 5))
funnel(res, yaxis="seinv", main="Inverse Standard Error", xlim = c(-5, 5))
funnel(res, yaxis="vinv", main="Inverse Sampling Variance", xlim = c(-5, 5))

Check data

Checked effect sizes with extremely high/low standard error (SE > 1.2 | 1/SE > 8.5) and confirmed that those data were correctly imported.

outliers <- var.dif %>%
  # vi (sampling variance) 
  mutate(SE = sqrt(lnCVR.sv)) %>%
  arrange(desc(SE)) %>%
  filter(SE > 1.2 | 1/SE > 8.5) %>%
  select(ES.ID, Study.name, SE, cross, Reciprocal, trait, Cross.ID) %>%
  mutate_if(is.numeric, round, 3)

outliers %>%
  kable("html", digits = 3, caption = "Effect sizes with extremely high/low standard error (SE > 1.2 | 1/SE > 140)") %>% 
  kable_styling("striped", position = "left") %>%
  scroll_box(width = "100%", height = "500px")
Effect sizes with extremely high/low standard error (SE > 1.2 | 1/SE > 140)
ES.ID Study.name SE cross Reciprocal trait Cross.ID
ES320 Musolf et al_2015 21.540 spL Inviable Frequ Modulated Downsweep_FAC1_2 musculus.3
ES253 Musolf et al_2015 10.257 hybSL Inviable Complex 2_FAC2_1 musculus.3
ES253 Musolf et al_2015 9.917 spL Inviable Complex 2_FAC2_1 musculus.3
ES147 Musolf et al_2015 6.096 spL Inviable U Shaped Inverted_FAC1_2 musculus.1
ES123 Musolf et al_2015 1.974 hybSL Inviable Complex 2_FAC2_1 musculus.1
ES320 Musolf et al_2015 1.933 hybLS Inviable Frequ Modulated Downsweep_FAC1_2 musculus.3
ES367 Suvanto et al_1994 1.656 hybSL Viable inhbt_IPI Drosophila_borealis_Drosophila_virilis
ES371 Suvanto et al_1994 1.617 spL Inviable inhbt_PL Drosophila_montana_Drosophila_virilis
ES125 Musolf et al_2015 1.376 spL Inviable Complex 2_FAC1_4 musculus.1
ES123 Musolf et al_2015 1.334 spL Inviable Complex 2_FAC2_1 musculus.1
ES254 Musolf et al_2015 1.265 spL Inviable Complex 2_FAC1_3 musculus.3
ES246 Musolf et al_2015 1.216 spL Inviable Complex 2_bandwcentre musculus.3
ES367 Suvanto et al_1994 1.205 spL Viable inhbt_IPI Drosophila_borealis_Drosophila_virilis
ES388 Tomaru&Oguma_1994 0.104 hybLS Inviable IPI Drosophila_triauraria_Drosophila_biauraria
ES041 Coyne_1985 0.087 hybSL Viable Sex comb tooth number BGxOxnard
ES387 Tomaru&Oguma_1994 0.076 spL Viable IPI Drosophila_triauraria_Drosophila_quadraria
ES390 Tomaru&Oguma_1994 0.075 hybLS Inviable IPI Drosophila_quadraria_Drosophila_subauraria
ES390 Tomaru&Oguma_1994 0.073 spL Inviable IPI Drosophila_quadraria_Drosophila_subauraria
ES041 Coyne_1985 0.071 spL Viable Sex comb tooth number BGxOxnard
ES041 Coyne_1985 0.071 hybLS Viable Sex comb tooth number BGxOxnard
ES389 Tomaru&Oguma_1994 0.071 spL Viable IPI Drosophila_quadraria_Drosophila_biauraria
ES388 Tomaru&Oguma_1994 0.064 spL Inviable IPI Drosophila_triauraria_Drosophila_biauraria
ES391 Tomaru&Oguma_1994 0.060 spL Viable IPI Drosophila_biauraria_Drosophila_subauraria
var.dif.2 <- var.dif %>%
  filter(!ES.ID %in% unique(outliers$ES.ID)) 
write.csv(var.dif.2, "../data/variation.ES.general.csv", row.names = F)

Because they inhibit meta-analytic model convergence, we excluded these outliers from the formal meta-analysis dataset, but not from novel variability dataset.

Funnel plots again

Funnel plots after outliers excluded

res <- rma(yi = lnCVR.es, vi = lnCVR.sv, data = var.dif.2, method="FE")
## set up 2x2 array for plotting
par(mfrow=c(2,2))
## draw funnel plots
funnel(res, main="Standard Error", xlim = c(-5, 5))
funnel(res, yaxis="vi", main="Sampling Variance", xlim = c(-5, 5))
funnel(res, yaxis="seinv", main="Inverse Standard Error", xlim = c(-5, 5))
funnel(res, yaxis="vinv", main="Inverse Sampling Variance", xlim = c(-5, 5))

Jugding novelty in phenotypic variabilities (using CV)

# load spLS files
dat <- read.csv("../data/dat.CV.csv", head = TRUE)

#+++++++++++++++++++++++++++++++++++++++++++++++++++++++#
# Difference between larger species (spL) and hybrids 
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++#

for (i in c("spL")) { # identify type of hybrids
  for (cr in c("hybLS", "hybSL")) { # identify type of parentals
    assign(
      paste(cr, i, sep = "_"),
        escalc(
          measure = "CVR",
          # N of hybrids
          n1i = dat[, paste("N", i, sep = ".")],
          # N of parentals
          n2i = dat[, paste("N", cr, sep = ".")],
          # Mean of hybrids
          m1i = dat[, paste("Mn", i, sep = ".")],
          # Mean of parentals
          m2i = dat[, paste("Mn", cr, sep = ".")],
          # SD of hybrids
          sd1i = dat[, paste("SD", i, sep = ".")],
          # SD of parentals
          sd2i = dat[, paste("SD", cr, sep = ".")],
          data = dat
          ) %>%
          select(ES.ID, yi, vi) %>%
          rename("lnCVR.es" = "yi", "lnCVR.sv" = "vi") %>% 
      mutate(
        # direction of transgressve segregation - greater than parent
        direction = "+",
        # SE for logistic distribution, for the weighted binomial regression
        # SE = pi/sqrt(3*(n_e + n_c))
        SE = pi/sqrt(3*(
          dat[, paste("N", i, sep = ".")] + dat[, paste("N", cr, sep = ".")]
        ))
      )
    )
  }
}

#+++++++++++++++++++++++++++++++++++++++++++++++++++++++#
# Difference between hybrids and smaller species (spS)
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++#

for (i in c("hybLS", "hybSL")) { # identify type of hybrids
  for (cr in c("spS")) { # identify type of parentals
    assign(
      paste(i, cr, sep = "_"),
        escalc(
          measure = "CVR",
          # N of hybrids
          n1i = dat[, paste("N", i, sep = ".")],
          # N of parentals
          n2i = dat[, paste("N", cr, sep = ".")],
          # Mean of hybrids
          m1i = dat[, paste("Mn", i, sep = ".")],
          # Mean of parentals
          m2i = dat[, paste("Mn", cr, sep = ".")],
          # SD of hybrids
          sd1i = dat[, paste("SD", i, sep = ".")],
          # SD of parentals
          sd2i = dat[, paste("SD", cr, sep = ".")],
          data = dat
          ) %>%
          select(ES.ID, yi, vi) %>%
          rename("lnCVR.es" = "yi", "lnCVR.sv" = "vi") %>% 
      mutate(
        # direction of transgressve segregation - smaller than parent
        direction = "-",
        # SE for logistic distribution, for the weighted binomial regression
        # SE = pi/sqrt(3*(n_e + n_c))
        SE = pi/sqrt(3*(
          dat[, paste("N", i, sep = ".")] + dat[, paste("N", cr, sep = ".")]
        ))
      )
    )
  }
}


#+++++++++++++++++++++++++++++++++++++++++++++++++++++++#
# Data output
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++#

bind_rows(
  ## Difference with mother species ###
  bind_rows(hybLS_spL, hybSL_spS) %>%
    mutate(parental = "Mother"),
  ## Difference with father species ###
  bind_rows(hybLS_spS, hybSL_spL) %>%
    mutate(parental = "Father")
  ) %>%
  drop_na(lnCVR.es) %>%
  left_join(., dat) %>%
  # Assign novel variability to 1, non-novel variability to 0 for each effect size
  mutate(Novelty = ifelse(lnCVR.es < 0, 1, 0)) %>%
  ## Join with metadata ###
  left_join(
    .,
    read.xlsx(
      "../data/original.data.xlsx", sheet = "Species.level.moderators"
      )
    ) %>%
  mutate_at(vars(contains("divergence")), as.numeric) %>%
  mutate_at(vars(contains("divergence")), scale) %>%
  as.data.frame %>%
  select(-trait) %>%
  drop_na(Hetero.sex, trait.type, Genet.divergence) %>%
  # order taxon
  within(
    taxa <- ordered(
      taxa,
      levels = c("Neuroptera", "Coleoptera", "Diptera", "Lepidoptera", "Orthoptera", "Aves", "Rodentia", "Anura", "Cichliformes")
      )
    ) %>%
  mutate_if(is.character, as.factor) %>%
  # Insect or no
  mutate(
    insect = ifelse(taxa %in% c("Aves", "Rodentia", "Anura", "Cichliformes"), "no", "insect"),
  ) %>%
  write.csv("../data/variation.ES.Novelty.csv", row.names = F)

Reload data & Prepare phylogenetic tree

# Load effect sizes
var.dif <- read.csv("../data/variation.ES.general.csv", head = TRUE)%>%
  # indicate dataset including novel variability
  mutate(data.type = "Alltraits")

# Observations with novel variability
All <- read.csv("../data/variation.ES.novelty.csv", head = TRUE) %>%
  filter(lnCVR.es < 0) %>%
  distinct(ES.ID)
# Effect sizes with non-novel variability
Nonovel <- read.csv("../data/variation.ES.general.csv", head = TRUE) %>%
  filter(!ES.ID %in% unique(All$ES.ID)) %>%
  # indicate dataset without novel variability
  mutate(data.type = "Nonnoveltraits")

# combine dataset with/without novel variability
Novel.Nonnovel <- bind_rows(var.dif, Nonovel) %>%
  mutate(metaunit =  str_c(data.type, cross, sep = "_")) %>%
  # Use observations with both reciprocal crosses
  drop_na(contains("Mn"), contains("SD")) %>%
  # Insect or no
  mutate(
    insect = ifelse(taxa %in% c("Cichliformes", "Anura", "Aves", "Rodentia"), "no", "insect"),
  )

#+++++++++++++++++++++++++++++++#
# Phylogeny 
#+++++++++++++++++++++++++++++++#

# # matching names from open tree taxonomy
# taxa <- tnrs_match_names(
#   names = levels(var.dif$spL.name) %>%
#     str_replace_all("_", " "), 
#   context_name = "Animals"
#   )
# 
# # Create tree
# tree <- tol_induced_subtree(ott_ids = taxa$ott_id)
# tree$tip.label %<>%
#   strip_ott_ids # remove OTT IDs from tip labels
# # randomly solve non-binary phylogeny
# set.seed(6)
# bin.tree <- multi2di(tree, random = T)
# 
# # Fix names of tip labels
# bin.tree$tip.label %<>% str_replace_all("Dryophytes", "Hyla")
# # Indicate mismatch between tip labels & dataset species names
# setdiff(levels(as.factor(bin.tree$tip.label)), levels(var.dif$spL.name))
# setdiff(levels(var.dif$spL.name), levels(as.factor(bin.tree$tip.label)))

# write.tree(bin.tree, file= "../data/phylo.variation.tre")

# compute branch lengths of tree
phylo_branch <- read.tree(file = "../data/phylo.variation.tre") %>%
  compute.brlen(bin.tree, method = "Grafen", power = 1)

# saving phylogeneic matrix
phylo_cor <- vcv(phylo_branch, cor = T)

# Note one of the tips is called "Lates calcarifer (estimated)"
phylo_branch$node.label <- NULL

# Plot tree
plot.phylo(phylo_branch, cex = 0.7)
Figure S2. Phylogenetic tree used in meta-analysis for phenotypic variability (coefficient of variation, CV), which was based on tree of the parental species with larger CV in trait size

Figure S2. Phylogenetic tree used in meta-analysis for phenotypic variability (coefficient of variation, CV), which was based on tree of the parental species with larger CV in trait size


Dominance in coefficient of variation (CV)

We compared midparent-value of phenotypic variability (CV) and hybrids’ phenotypic variability by calculating log ratio of phenotypic variability (lnCVR) of midparent-value and hybrids to spSSV.

lnCVR of midparent-value to spSSV was, following \(lnCVR=\ln{\frac{CV_E}{CV_C}}+\frac{1}{2(N_E-1)}-\frac{1}{2(N_C-1)}\) , calculated as
\[\ln\frac{CV_{spLL_V}+CV_{spSS_V}}{2}-\ln{CV_{spSS_V}} + \frac{1}{N_{spLL_V}+N_{spSS_V}-2}-\frac{1}{2(N_{spSS_V} - 1)}\] It’s sampling variance was substitute by that of spLLV

We statistically compared those effect sizes through the formal meta-regression by using rma.mv function of R package metafor

All meta-analytic models included following Random effects estimates:

  • Study.ID: Primary studies. Denoted as Study

  • Cross.ID: Parental strain used in the crossing. Discriminate intraspecific populations. Denoted as crossed strain

  • spL.name: Phylogeny of parental species (spLLM). Denoted as species with phylogeny

#+++++++++++++++++++++++++++++++++++++++++++#
# Calculate midparent 
#+++++++++++++++++++++++++++++++++++++++++++#
midparent <- Novel.Nonnovel %>%
  # Divide mean by 2 in spL whereas hybrids are constant
   mutate(
     CV.spL = SD.spL/Mn.spL,
     CV.spS = SD.spS/Mn.spS
     ) %>%
   mutate(
     lnCVR.midparent.es =
       ifelse(
         cross == "spL",
         # log(CVe/CVc)
         log((CV.spL + CV.spS)/2) - log(CV.spS) +  
           # 1/2(Ne-1) - 1/2(Nc-1)
           1/(N.spL + N.spS -2) - 1/(2*N.spS - 2), 
         lnCVR.es
         )
     # Divide variance by 4 in spL whereas hybrids are constant
     ) %>%
   mutate_at("cross", as.factor) %>%
   within(levels(cross) <- c("hybLS", "hybSL", "midparent"))


#+++++++++++++++++++++++++++++++++++++++++++++++++++#
# Compare midparent and hybrids by meta-regresson
#+++++++++++++++++++++++++++++++++++++++++++++++++++#

for (tr in c("Alltraits", "Nonnoveltraits")) {
  for (taxon in c("alltaxon", "insect")) {
    
    # Filtering taxon (all taxon or insects)
    if (taxon == "alltaxon") {
      dat <- midparent %>% 
        filter(data.type == tr)
    } else {
      dat <- midparent %>% 
        filter(data.type == tr, insect == taxon)
    }

    # #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
    # # Estimate meta-analytic mean of midparent of phenotypic variation
    # #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
    # midparent.compare <- rma.mv(
    #   yi = lnCVR.midparent.es, V = lnCVR.sv,
    #   data = dat,
    #   method = "REML",
    #   random = list(~1 | spL.name, ~1 | Study.ID, ~1 | Cross.ID, ~1 | ES.ID),
    #   R = list(spL.name = phylo_cor),
    #   mods = ~ relevel(cross, ref = "midparent")
    #   )
    # ## Save model ###
    # saveRDS(
    #   midparent.compare,
    #   file = paste("../Analysis/Variation.midparent.compare", tr, taxon, "obj", sep = ".")
    #   )
  
    ## Load model ###
    midparent.compare <- readRDS(paste("../Analysis/Variation.midparent.compare", tr, taxon, "obj", sep = "."))
    
    assign(
      paste("Dominance", tr, taxon, sep = "."),
      get_reg(midparent.compare) %>%
        # Show dataset name
        within(Dataset <- c(paste(tr, taxon), rep("", length(.$Estimate)-1))) %>%
        # Rename fixed effects
        within('Fixed effects' <- c("", "midparent (intrcpt)", "hybLS", "hybSL")) %>%
        # Difference of each cross from midparent in %
        mutate('Comparison with midparent' = c(
          rep("", 2),
          # Difference hybLS - midparent
          paste(
            round(
            100*(exp(midparent.compare$beta[1]+midparent.compare$beta[2])            -exp(midparent.compare$beta[1])), # hybrid LS
            2),
            "% larger"
            ),
              # beta[1] : midparent
              # beta[2] : hybLS
              # beta[3] : hybSL
          # Difference hybSL - midparent
          paste(
            round(
            100*(exp(midparent.compare$beta[1]+midparent.compare$beta[3])-exp(midparent.compare$beta[1])), # hybrid SL
            2),
            "% larger"
            )
          ))
      )

    # #++++++++++++++++++++++++++++++++++++++++++++++#
    # # Meta-analysis for midparent to plot band
    # #++++++++++++++++++++++++++++++++++++++++++++++#
    # 
    # # Phylogenetic random meta-analysis
    # midparent.random <- rma.mv(
    #   yi = lnCVR.midparent.es,
    #   V = lnCVR.sv,
    #   data = dat %>%
    #     filter(cross == "midparent"),
    #   method = "REML",
    #   random = list(~1 | spL.name, ~1 | Study.ID, ~1 | Cross.ID, ~1 | ES.ID),
    #   R = list(spL.name = phylo_cor)
    #   )
    # ## Save model ###
    # saveRDS(
    #   midparent.random,
    #   file = paste("../Analysis/Variation.midparent", tr, taxon, "obj", sep = ".")
    #   )
    
  }
}

bind_rows(
  Dominance.Alltraits.alltaxon, Dominance.Nonnoveltraits.alltaxon,
  Dominance.Alltraits.insect, Dominance.Nonnoveltraits.insect
  ) %>%
  kable("html", digits = 3, caption = "Table S5. Results of meta-analysis investigating dominance in phenotypic variabilities using full dataset or data subsets") %>%
  kable_styling("striped", position = "left") %>%
  scroll_box(width = "100%", height = "500px")
Table S5. Results of meta-analysis investigating dominance in phenotypic variabilities using full dataset or data subsets
Dataset Fixed effects Estimate LowerCI UpperCI P I2[total] %I2[species with phylogeny] %I2[study] %I2[crossed strain] %I2[residual] significance Comparison with midparent
Alltraits alltaxon 75.6% 19.5% 11.4% 0% 44.7%
midparent (intrcpt) 0.381 0.079 0.682 0.013
hybLS -0.020 -0.098 0.058 0.610 -2.94 % larger
hybSL -0.091 -0.170 -0.013 0.022
-12.77 % larger
Nonnoveltraits alltaxon 69.9% 14.4% 21% 0% 34.5%
midparent (intrcpt) 0.589 0.275 0.902 0.000
hybLS -0.146 -0.257 -0.035 0.010
-24.49 % larger
hybSL -0.144 -0.254 -0.033 0.011
-24.13 % larger
Alltraits insect 67.8% 0.1% 15.3% 0% 52.4%
midparent (intrcpt) 0.261 0.118 0.404 0.000
hybLS -0.016 -0.096 0.064 0.695 -2.06 % larger
hybSL -0.113 -0.193 -0.032 0.006
-13.82 % larger
Nonnoveltraits insect 56.9% 0% 24.4% 0% 32.5%
midparent (intrcpt) 0.452 0.259 0.645 0.000
hybLS -0.144 -0.258 -0.030 0.013
-21.11 % larger
hybSL -0.173 -0.287 -0.059 0.003
-24.94 % larger

Univarate meta-analysis for each cross (using CV)

Quantify and visualise overall trend of phenotypic variability (CV) of hybrids compared to parents
Meta-analysis was repeated for subset data - including only non-novel phenotypes, only insects, and non-novel phenotypes in insects
Meta-analysis was conducted by using rma.mv function in metafor package

  • Confidential interval : thick line

  • Prediction interval : thin line

for (tr in c("Alltraits", "Nonnoveltraits")) {
  for (taxon in c("alltaxon", "insect")) {

    if (taxon == "alltaxon") {
      dat <- Novel.Nonnovel %>%
        filter(cross == cr, data.type == tr)
    } else {
      dat <- Novel.Nonnovel %>%
        filter(cross == cr, data.type == tr, insect == taxon)
    }
    
    res.ma <- foreach(
      cr = c("spL", "hybLS", "hybSL"), .combine = `rbind`
      ) %do% {
      # # Phylogenetic random meta-analysis
      # phyl.random <- rma.mv(
      #   yi = lnCVR.es, V = lnCVR.sv,
      #   data = dat, method = "REML",
      #   random = list(~1 | spL.name, ~1 | Study.ID, ~1 | Cross.ID, ~1 | ES.ID),
      #   R = list(spL.name = phylo_cor)
      #   )
      # saveRDS(phyl.random,
      #   file = paste("../Analysis/Variation.meta", tr, taxon, cr, "obj", sep = "."))

      # creating summary table of results
      readRDS(
        paste("../Analysis/Variation.meta", tr, taxon, cr, "obj", sep = ".")
        ) %>%
          get_pred() %>%
          as.data.frame() %>%
          mutate(
            N = length(dat$ES.ID),
            # I2 = I2(phyl.random)["I2_total"] %>% round(3),
            cross = cr # indicate cross (spL, hybLS, hybSL)
            ) %>% 
        as.data.frame() %>%
        within('Dataset' <- c(paste(tr, taxon), "", "")) %>%  # dataset name in first row
        return()
        }

    if (taxon == "alltaxon") {
      dat.plot <- Novel.Nonnovel %>% 
        filter(data.type == tr)
    } else {
      dat.plot <- Novel.Nonnovel %>% 
        filter(data.type == tr, insect == taxon)
    }
    
    # Bind result of all crosses at each dataset
    assign(
      paste("res.ma", tr, taxon, sep = "."),
      res.ma
    )
    
    ## Midparent estimate & CI ###
    midparent.ma.2 <- readRDS(
      paste("../Analysis/Variation.midparent", tr, taxon, "obj", sep = ".")
      ) %>% 
      # Prediction interval of midparent
      get_pred() %>%
      as.data.frame()
    
    # creating a forest plot
    plot.metamean <- ggplot(
      data = res.ma,
      aes(x = tanh(Estimate), y = cross)
      ) +
      scale_y_discrete(expand = c(0,1)) +
      scale_x_continuous(
        limits = c(-1, 1),
        breaks = seq(-1, 1, by = 0.5)
        ) +
      ## Midparent CI ###
      geom_rect(
        aes(
          xmin = tanh(midparent.ma.2$LowerCI),
          xmax = tanh(midparent.ma.2$UpperCI),
          ymin = -Inf, ymax = Inf
          ),
        fill="Grey 95", inherit.aes = FALSE
        ) +
      ## Midparent estimate ###
      geom_vline(
        xintercept = tanh(midparent.ma.2$Estimate), colour = "grey20",
        alpha = 0.3, size = 1
        ) +
      ## Orchard plot ###
      geom_quasirandom(
        data = dat.plot %>%
          filter(data.type == tr),
        aes(x = tanh(lnCVR.es), y = cross, size = 1/lnCVR.sv, color = cross),
        alpha = 0.2, GroupOnX = FALSE
        ) +
      scale_color_manual(values = c("#DC267F", "#785EF0", "#FE6100")) +
      # Delete legend for colors
      guides(fill = "none", colour = "none") +
      ## Confidential interval ###
      geom_errorbarh(
        aes(xmin = tanh(LowerCI), xmax = tanh(UpperCI)),
        height = 0, size = 1.2, alpha = 0.6
        ) +
      ## Prediction interval ###
      geom_errorbarh(
        aes(xmin = tanh(lowerPR), xmax = tanh(upperPR)),
        height = 0.1, size = 0.5, alpha = 0.6
        ) +
      geom_vline(xintercept = 0, linetype = 2, colour = "black", alpha = 0.3) +
      ## Estimate ###
      geom_point(size = 3, shape = 21, fill = "black") +
      ## N ###
      annotate(
        "text", x = -0.93, y = 3.85,
        label = paste("italic(N)==", length(dat.plot$ES.ID)/3),
        parse = TRUE, hjust = "left", size = 5
      ) +
      annotate(
        "text", x = -0.68, y = 3.85,
        label = "each", hjust = "left", size = 5
      ) +
      ylab("") +
      xlab(expression(
        paste("hyperbolic tangent of lnCVR from ", italic("spSS")),
        parse = TRUE
        )) +
      ggtitle(cap[paste(tr, taxon,sep="."),]) +
      orchardtheme 
    
    print(plot.metamean)

    # ggsave(
    #   plot = plot.metamean,
    #   file = paste("../Analysis/variation.general.metamean", tr, taxon, "svg", sep = "."),
    #   height = 4, width = 5
    # )

  }
}

bind_rows(
  res.ma.Alltraits.alltaxon, res.ma.Nonnoveltraits.alltaxon,
  res.ma.Alltraits.insect, res.ma.Nonnoveltraits.insect
  ) %>%
  as.data.frame() %>%
  select(Dataset, cross, Estimate, UpperCI, LowerCI, contains("PR"), contains("I2")) %>%
  kable("html", digits = 3, caption = "Meta-analyses results of full dataset and data subsets") %>% 
  kable_styling("striped", position = "left") %>%
  scroll_box(width = "100%", height = "500px")
Meta-analyses results of full dataset and data subsets
Dataset cross Estimate UpperCI LowerCI lowerPR upperPR I2[total] %I2[species with phylogeny] %I2[study] %I2[crossed strain] %I2[residual]
Alltraits alltaxon spL 0.538 0.763 0.314 -0.240 1.317 68.9% 12.7% 12.1% 0% 44.1%
Alltraits alltaxon hybLS 0.302 0.531 0.073 -0.913 1.516 82.4% 3.2% 10.8% 0% 68.4%
Alltraits alltaxon hybSL 0.345 0.790 -0.101 -1.048 1.738 84.8% 24.5% 18.4% 0% 41.8%
Nonnoveltraits alltaxon spL 0.734 0.983 0.485 -0.265 1.733 77.2% 0% 29.1% 0% 48.1%
Nonnoveltraits alltaxon hybLS 0.402 0.646 0.157 -0.567 1.371 69.6% 0% 24% 0% 45.7%
Nonnoveltraits alltaxon hybSL 0.556 1.161 -0.049 -0.722 1.834 77% 66.9% 0% 0% 10.2%
Alltraits insect spL 0.446 0.570 0.322 -0.181 1.073 61.4% 0% 14.2% 0% 47.3%
Alltraits insect hybLS 0.226 0.403 0.048 -0.892 1.343 80.5% 0% 8.9% 0% 71.6%
Alltraits insect hybSL 0.151 0.362 -0.061 -0.957 1.259 79.5% 0% 23.3% 0% 56.2%
Nonnoveltraits insect spL 0.647 0.870 0.424 -0.185 1.479 70.2% 0% 24.3% 0% 45.9%
Nonnoveltraits insect hybLS 0.317 0.543 0.091 -0.488 1.122 60.6% 0% 22.1% 0% 38.5%
Nonnoveltraits insect hybSL 0.256 0.437 0.076 -0.222 0.735 33.5% 0% 21% 11% 1.5%

Crossing direction effect in phenotypic variability (CV)

We statistically compared lnCVR from spSSM to the other crosses through the formal meta-regression by using rma.mv function of R package metafor.
Here we asked if lnCVR of hybSLV was smaller/larger than that of hybLSV. Smaller lnCVR of hybSLV indicates maternal inheritance in phenotypic variability

for (tr in c("Alltraits", "Nonnoveltraits")) {
  for (taxon in c("alltaxon", "insect")) {
    
    if (taxon == "alltaxon") {
      dat <- Novel.Nonnovel %>% 
        filter(data.type == tr)
    } else {
      dat <- Novel.Nonnovel %>% 
        filter(data.type == tr, insect == taxon)
    }

  #++++++++++++++++++++++++++++++++++++++++++++++#
  # phylogenetic random regresson (ANOVA)
  #++++++++++++++++++++++++++++++++++++++++++++++#
    
  # # Regress by lnCVR of phenotypic difference between parentals
  # phyl.random.spL <- rma.mv(
  #   yi = lnCVR.es, V = lnCVR.sv,
  #   data = dat, method = "REML",
  #   random = list(~1 | spL.name, ~1 | Study.ID, ~1 | Cross.ID, ~1 | ES.ID),
  #   R = list(spL.name = phylo_cor),
  #   mods = ~ relevel(cross, ref = "spL")
  #   )
  # phyl.random.hybLS <- rma.mv(
  #   yi = lnCVR.es, V = lnCVR.sv,
  #   data = dat, method = "REML",
  #   random = list(~1 | spL.name, ~1 | Study.ID, ~1 | Cross.ID, ~1 | ES.ID),
  #   R = list(spL.name = phylo_cor),
  #   mods = ~ cross
  #   )
  # # Save model ###
  # saveRDS(
  #   phyl.random.spL,
  #   file = paste("../Analysis/Variation.compare.from.spL", tr, taxon, "obj", sep = ".")
  #   )
  # saveRDS(
  #   phyl.random.hybLS,
  #   file = paste("../Analysis/Variation.compare.from.hybLS", tr, taxon, "obj", sep = ".")
  #   )
    
    phyl.random.hybLS <- readRDS(
      paste("../Analysis/Variation.compare.from.hybLS", tr, taxon, "obj", sep = ".")
      )

  assign(
    paste("Reciprocal", tr, taxon, sep = "."),
    phyl.random.hybLS %>% 
      get_reg() %>%
      # Show dataset name
      within(Dataset <- c(paste(tr, taxon), rep("", length(.$Estimate)-1))) %>%
      # Rename fixed effects
      within('Fixed effects' <- c("", "hybLS (intrcpt)", "hybSL", "spLL")) %>%
      # Difference of each cross from midparent in %
      mutate('Comparison with hybridLS' = c(
        rep("", 2),
        paste(
          round(
            (exp(phyl.random.hybLS$beta[1]+phyl.random.hybLS$beta[2]) - exp(phyl.random.hybLS$beta[1]))*100,
            2),
          "% larger"
          ), 
        ""
        )
      )
    )
  }
}

bind_rows(
  Reciprocal.Alltraits.alltaxon, Reciprocal.Nonnoveltraits.alltaxon,
  Reciprocal.Alltraits.insect, Reciprocal.Nonnoveltraits.insect
  ) %>%
  kable("html", digits = 3, caption = "Table S6. Results of meta-analysis investigating cross direction effect in phenotypic variabilities using full dataset or data subsets") %>% 
  kable_styling("striped", position = "left") %>%
  scroll_box(width = "100%", height = "500px")
Table S6. Results of meta-analysis investigating cross direction effect in phenotypic variabilities using full dataset or data subsets
Dataset Fixed effects Estimate LowerCI UpperCI P I2[total] %I2[species with phylogeny] %I2[study] %I2[crossed strain] %I2[residual] significance Comparison with hybridLS
Alltraits alltaxon 78.2% 20.1% 9.6% 0% 48.5%
hybLS (intrcpt) 0.377 0.055 0.700 0.022
hybSL -0.074 -0.155 0.006 0.070 -10.44 % larger
spLL 0.190 0.112 0.268 0.000
Nonnoveltraits alltaxon 73.8% 10.2% 23% 0% 40.6%
hybLS (intrcpt) 0.451 0.136 0.766 0.005
hybSL -0.002 -0.118 0.114 0.973 -0.31 % larger
spLL 0.362 0.251 0.474 0.000
Alltraits insect 72.1% 0.8% 14.2% 0% 57.1%
hybLS (intrcpt) 0.258 0.095 0.420 0.002
hybSL -0.100 -0.183 -0.016 0.019
-12.26 % larger
spLL 0.178 0.098 0.258 0.000
Nonnoveltraits insect 65.2% 0% 24.7% 0% 40.5%
hybLS (intrcpt) 0.329 0.107 0.550 0.004
hybSL -0.032 -0.153 0.088 0.598 -4.42 % larger
spLL 0.354 0.240 0.468 0.000

Novelty in phenotypic means

Frequency

dat.full <- read.csv("../data/mean.ES.Novelty.csv", head = TRUE)

## N of novel phenotype in each taxa and each direction ###
summary <- bind_rows(
  # All observations
  dat.full %>%
    group_by(taxa) %>%
    summarise(
      'Species pair' = length(unique(species.pair)),
      Observations = length(unique(ES.ID)),
      Study = length(unique(Study.ID))
      ) %>%
    mutate(direction = "All Observations")
  ,
  # novel phenotype for any direction
  dat.full %>%
    filter(Novelty == "1") %>%
    group_by(taxa) %>%
    summarise(
      'Species pair' = length(unique(species.pair)),
      Observations = length(unique(ES.ID)),
      Study = length(unique(Study.ID))
      ) %>%
    mutate(direction = "Novel phenotypic means")
  ,
  # novel phenotype for each direction
  dat.full %>%
    filter(Novelty == "1") %>%
    group_by(taxa, direction) %>%
    summarise(
      'Species pair' = length(unique(species.pair)),
      Observations = length(unique(ES.ID)),
      Study = length(unique(Study.ID))
      )
  ) %>%
  # Assign 0 for non-novel phenotype
  replace(., is.na(.), "0") %>% 
  # Make tidy data
  gather(key = metrics, value = N, -c(taxa, direction)) %>%
  # Order factors
  mutate_at(vars("metrics", "direction"), as.factor) %>%
  filter(metrics != "Study")

# Order taxon
summary$metrics <- ordered(summary$metrics, levels = c("Study", "Species pair", "Observations"))
# Order novel phenotype category
summary$direction <- ordered(summary$direction, levels = c("All Observations", "Novel phenotypic means", "+", "-"))
# Change names of TS category to more intuitive name
levels(summary$direction) <- c("All Observations", "Novel phenotypic means", "Exceed upper range", "Exceed lower range")

## Plot ###
plot <- ggplot(
  # rename levels of factors to wrap label text
  summary %>%
    within(levels(direction) <- c("All Obser- vations", "Novel phenotypic means", "Exceed upper range", "Exceed lower range")) %>%
    within(levels(metrics) <- c("Study", "Species pair", "Obser- vations")), 
  aes(x = "", y = N, fill = taxa)) +
  geom_bar(width = 1, stat = "identity") +
  scale_fill_brewer(palette = "Paired") +
  facet_grid(
    scale = "free", metrics ~ direction,
    # strip text into two lines
    labeller = label_wrap_gen(width = 10)
    ) +
  xlab("") + ylab("") +
  stackedbartheme
plot +
  ggtitle("Taxonomic distribution of novel phenotypic means")

# ggsave(
#   plot = plot, 
#   file = "../Analysis/mean.TS.frequency.svg", height = 3.7, width = 5.0
#   )

## Total number of observations and percentage ###
summary %>%
  group_by(direction, metrics) %>%
  # Count number of observaitons and species pairs
  summarise(sum(N)) %>%
  spread(key = metrics, value = "sum(N)") %>%
  as.data.frame() %>%
  # Calculate percentage
  mutate(
    'Species pair %' = .[, "Species pair"]/.[1, "Species pair"]*100,
    'Observaton %' = Observations/.[1, "Observations"]*100
  ) %>%
  mutate_at(vars(contains("percent")), round, 2) %>%
  kable("html", digits = 3, caption = "Summary of the novel phenotypic means frequency") %>% 
  kable_styling("striped", position = "left")
Summary of the novel phenotypic means frequency
direction Species pair Observations Species pair % Observaton %
All Observations 34 332 100.000 100.000
Novel phenotypic means 22 143 64.706 43.072
Exceed upper range 15 71 44.118 21.386
Exceed lower range 11 74 32.353 22.289

Factors affecting phenotypic novelty

We checked robustness of results by conducting identical analysis for insect subset data (removing vertebrate data).

Model, which was ran using MCMCglmm function, included following Random effects estimates:

  • Study.ID: Primary studies

  • Cross.ID: Parental strain used in the crossing. Discriminate intraspecific populations

  • spL.name: Phylogeny of parental species (spLLM)

  • SE.units: Sampling variance of effect size

The moderators were categorised into 3 subsets: main effects (labelled as novelty in phenotypic means), interaction terms with compared parental species (spLL vs. spSS, labelled as exceed upper range; mother species vs. father, labelled as exceed mother).

# Correcting estimate of binomial regression
c2 <- (16 * sqrt(3)/(15 * pi))^2


#++++++++++++++++++++++++++++++++++#
# Phylogenetic tree for mcmcglmm 
#++++++++++++++++++++++++++++++++++#
# compute branch lengths of tree
phylo_branch <- read.tree(file = "../data/phylo.mean.tre") %>%
  compute.brlen(method = "Grafen", power = 1)

# saving phylogeneic matrix
phylo_cor <- vcv(phylo_branch, cor = T)

# generating inverse phylogenetic matrix for MCMCglmm
phylo_branch$node.label <- NULL
phylo_MCMC <- MCMCglmm::inverseA(phylo_branch, nodes = "ALL", scale = TRUE)$Ainv

# Caption
cap <- data.frame(
  desc = c(
    "Table S7. Fixed effects estimates of Bayesian logistic model investigating factors affecting novelty in phenotypic means. Data of all taxon was used",
    "Fixed effects estimates: insect subset data"
    )
  ) %>%
  mutate_all(as.character)
row.names(cap) <- c("alltaxon", "insect")

for (taxon in c("alltaxon", "insect")) {
  
  if (taxon == "alltaxon") {
    dat <- dat.full
  } else {
    dat <- dat.full %>% 
      filter(insect == taxon)
  }

  # ## Setting prior to logistic regression ###
  # prior <- list(
  #   B=list(
  #     mu = rep(0, 17), # N of coefficient. (level -1) for categorical factors, 1 for continuous factors, 1 for intercept
  #     V = gelman.prior(~
  #       parental*Hetero.sex +
  #       parental*direction +
  #       direction*Genet.divergence + direction*Pheno.divergence +
  #       direction*Hetero.sex +
  #       direction*trait.type +
  #       direction*Distribution + direction*Reciprocal,
  #     data = dat, # formula and data
  #     scale=sqrt(pi^2/3+1))), # error distribution of logistic regression
  #   R=list(V=1,fix=1),
  #   G = list(
  #     G1 = list(V = 1, nu = 1, alpha.mu = 0, alpha.V = 1000),
  #     G2 = list(V = 1, nu = 1, alpha.mu = 0, alpha.V = 1000),
  #     G3 = list(V = 1, nu = 1, alpha.mu = 0, alpha.V = 1000),
  #     G4 = list(V = 1, nu = 1, alpha.mu = 0, alpha.V = 1000)
  #     )
  #   )
  # ## Phylogenetic binomial regression ###
  # phylmix <-MCMCglmm(
  #   fixed = Novelty ~
  #     parental*Hetero.sex + parental*direction +
  #     direction*Genet.divergence + direction*Pheno.divergence +
  #     direction*Hetero.sex + direction*trait.type +
  #     direction*Distribution + direction*Reciprocal,
  #   # idh(SE):units | weight by SE of effect size
  #   random = ~ Study.ID + Cross.ID + spL.name + idh(SE):units,
  #   family = "categorical",
  #   verbose = FALSE,
  #   ginverse = list(spL.name = phylo_MCMC),
  #   prior = prior,
  #   data = dat,
  #   nitt = 60000,  # Increase the number of iterations, default is 13000
  #   burnin = 5000  # Increase the number of burnin, default is 3000
  # )
  # phylmix$Sol <- phylmix$Sol/sqrt(1+c2)
  # ## Save model ###
  # saveRDS(phylmix, file = paste("../Analysis/Mean.novelty.allfactors", taxon, "obj", sep = "."))

  #+++++++++++++++++++++++#
  # Grouping variables
  #+++++++++++++++++++++++#
  # Load model
  phylmix <- readRDS(paste("../Analysis/Mean.novelty.allfactors", taxon, "obj", sep = "."))
  
  sum <- get_fixed.MCMCglmm(summary(phylmix)$solutions) %>%
      ## Grouping Factors ###
      mutate(
        Group = 
          ifelse(str_detect(Factors, "direction.:"), 
                 "Exceed upper range",
                 ifelse(str_detect(Factors, "parentalMother:"),
                        "Exceed mother",
                        ifelse(Factors == "Hetero.sexMale:direction+",
                               "Exceed upper range",
                               "Increase novelty"
                               )
                        )
                 )
      ) %>%
      mutate_at("Group", as.factor) %>%
      within(Group <- ordered(Group, c("Increase novelty", "Exceed upper range", "Exceed mother"))) %>%
      ## Change factor names ###
      within(
        Factors <- str_remove_all(
          Factors, "direction.:"
          ) %>%
          str_remove_all(., "parentalMother:") %>%
          str_remove_all(., ":direction.")
        ) %>%
      within(
        Factors <- factor(
          Factors, ordered = TRUE, 
          levels = c("parentalMother", "direction+", "trait.typesound", "Hetero.sexMale", "ReciprocalViable", "DistributionOverlap", "Pheno.divergence",  "Genet.divergence",  "(Intercept)")
          )
        )
  levels(sum$Factors) <- c("Exceed mother", "Exceed upper range", "Sound traits", "Male heterogametic", "Viable reciprocal hybrids", "Distribution overlap", "Phenotypic divergence", "Genetic divergence", "Intercept")

  ## Plot ###
  metaplot <- ggplot(sum, aes(x = post.mean, y = Factors)) +
    # Vertical line
    geom_vline(
      xintercept = 0, size = 0.2, 
      colour = "grey30", linetype = "dotted"         
      ) +
    # CI
    geom_errorbarh(
      aes(
        xmin = sum[, 'l-95% CI'], xmax = sum[, 'u-95% CI'],
        colour=significance 
        ), 
      height = .0001
      ) +
    # Color of plots and errorbars
    scale_colour_manual(values = c("grey60", "black")) +
    geom_point(size = 1, aes(colour = significance)) +
    scale_fill_manual(values = c("grey60", "black")) +
    # Title
    ggtitle(paste("Fixed effects estimates using", taxon, "data")) +
    ylab("") + xlab("Estimate with 95% CI") +
    # Combine different plots for main Factors and interactions
    facet_grid(
      Group~., scales = "free", space = "free",
      labeller = label_wrap_gen(width = 20)
      ) +
    # Themes
    foresttheme
print(metaplot)

  # ggsave(
  #     plot = metaplot,
  #     file = paste("../Analysis/mean.novelty.result", taxon, "svg", sep = "."),
  #     height = 4.7, width = 4.0
  #     )

  #+++++++++++++++++++++++++#
  # Fixed effects output
  #+++++++++++++++++++++++++#
  sum %>% 
    select(Group, Factors, Estimates, '95% credible interval', P, significance, Description) %>%
    kable("html", caption = cap[taxon,]) %>% 
    kable_styling("striped", position = "left") %>%
    scroll_box(width = "100%", height = "500px") %>%
    print()
  
  #+++++++++++++++++++++++++++#
  # Random effects output 
  #+++++++++++++++++++++++++++#
  # transformation for varaince
  get_random.MCMCglmm(summary(phylmix$VCV/(1+c2))) %>%
    kable("html", digits = 2,
          caption = paste("Random effects estimates: ", taxon, "data", " ")
          ) %>% 
    kable_styling("striped", position = "left") %>%
    print()

}
Table S7. Fixed effects estimates of Bayesian logistic model investigating factors affecting novelty in phenotypic means. Data of all taxon was used
Group Factors Estimates 95% credible interval P significance Description
Increase novelty Intercept -1.82 -5.19 – 1.64 0.269 \(\beta\) = -1.82, CI = -5.19 – 1.64, P = 0.269
Increase novelty Exceed mother -0.33 -2.49 – 1.57 0.743 \(\beta\) = -0.33, CI = -2.49 – 1.57, P = 0.743
Increase novelty Male heterogametic -0.46 -2.87 – 2.16 0.717 \(\beta\) = -0.46, CI = -2.87 – 2.16, P = 0.717
Increase novelty Exceed upper range 0.25 -1.9 – 2.41 0.833 \(\beta\) = 0.25, CI = -1.9 – 2.41, P = 0.833
Increase novelty Genetic divergence 0.26 -0.41 – 0.9 0.420 \(\beta\) = 0.26, CI = -0.41 – 0.9, P = 0.42
Increase novelty Phenotypic divergence -0.80 -1.48 – -0.23 0.000
\(\beta\) = -0.8, CI = -1.48 – -0.23, P = 0
Increase novelty Sound traits 0.94 -1.14 – 2.94 0.357 \(\beta\) = 0.94, CI = -1.14 – 2.94, P = 0.357
Increase novelty Distribution overlap -1.39 -3.54 – 0.52 0.138 \(\beta\) = -1.39, CI = -3.54 – 0.52, P = 0.138
Increase novelty Viable reciprocal hybrids -1.36 -2.97 – 0.04 0.064 \(\beta\) = -1.36, CI = -2.97 – 0.04, P = 0.064
Exceed mother Male heterogametic 1.68 -0.38 – 3.63 0.104 \(\beta\) = 1.68, CI = -0.38 – 3.63, P = 0.104
Exceed mother Exceed upper range -0.84 -1.99 – 0.35 0.156 \(\beta\) = -0.84, CI = -1.99 – 0.35, P = 0.156
Exceed upper range Genetic divergence -0.59 -1.19 – 0.02 0.041
\(\beta\) = -0.59, CI = -1.19 – 0.02, P = 0.041
Exceed upper range Phenotypic divergence 0.08 -0.57 – 0.74 0.790 \(\beta\) = 0.08, CI = -0.57 – 0.74, P = 0.79
Exceed upper range Male heterogametic 0.69 -1.6 – 2.77 0.532 \(\beta\) = 0.69, CI = -1.6 – 2.77, P = 0.532
Exceed upper range Sound traits -1.35 -3.14 – 0.3 0.116 \(\beta\) = -1.35, CI = -3.14 – 0.3, P = 0.116
Exceed upper range Distribution overlap -0.30 -1.95 – 1.33 0.715 \(\beta\) = -0.3, CI = -1.95 – 1.33, P = 0.715
Exceed upper range Viable reciprocal hybrids 2.51 1.01 – 4.01 0.001
\(\beta\) = 2.51, CI = 1.01 – 4.01, P = 0.001
Random effects estimates: alltaxon data
Random effects Estimates 95% credible interval
Study.ID 1.37 0–6.03
Cross.ID 0.42 0–2.53
spL.name 4.16 0–26.95
SE.units 15.59 0.07–84.7
units 0.74 0.74–0.74
Fixed effects estimates: insect subset data
Group Factors Estimates 95% credible interval P significance Description
Increase novelty Intercept -0.62 -5.59 – 4.89 0.800 \(\beta\) = -0.62, CI = -5.59 – 4.89, P = 0.8
Increase novelty Exceed mother -0.23 -2.57 – 2.11 0.845 \(\beta\) = -0.23, CI = -2.57 – 2.11, P = 0.845
Increase novelty Male heterogametic -0.01 -3.11 – 3.38 0.996 \(\beta\) = -0.01, CI = -3.11 – 3.38, P = 0.996
Increase novelty Exceed upper range 0.79 -1.88 – 3.39 0.560 \(\beta\) = 0.79, CI = -1.88 – 3.39, P = 0.56
Increase novelty Genetic divergence 0.06 -0.94 – 0.92 0.851 \(\beta\) = 0.06, CI = -0.94 – 0.92, P = 0.851
Increase novelty Phenotypic divergence -1.28 -2.23 – -0.3 0.004
\(\beta\) = -1.28, CI = -2.23 – -0.3, P = 0.004
Increase novelty Sound traits 0.39 -2.55 – 3.3 0.773 \(\beta\) = 0.39, CI = -2.55 – 3.3, P = 0.773
Increase novelty Distribution overlap -1.76 -4.63 – 1.01 0.223 \(\beta\) = -1.76, CI = -4.63 – 1.01, P = 0.223
Increase novelty Viable reciprocal hybrids -0.90 -3.27 – 1.32 0.435 \(\beta\) = -0.9, CI = -3.27 – 1.32, P = 0.435
Exceed mother Male heterogametic 0.76 -1.55 – 3.24 0.531 \(\beta\) = 0.76, CI = -1.55 – 3.24, P = 0.531
Exceed mother Exceed upper range -0.03 -2.06 – 2.01 0.943 \(\beta\) = -0.03, CI = -2.06 – 2.01, P = 0.943
Exceed upper range Genetic divergence -0.77 -1.55 – -0.03 0.042
\(\beta\) = -0.77, CI = -1.55 – -0.03, P = 0.042
Exceed upper range Phenotypic divergence -0.47 -1.54 – 0.54 0.369 \(\beta\) = -0.47, CI = -1.54 – 0.54, P = 0.369
Exceed upper range Male heterogametic 1.88 -0.7 – 4.68 0.160 \(\beta\) = 1.88, CI = -0.7 – 4.68, P = 0.16
Exceed upper range Sound traits -0.97 -3.41 – 1.38 0.416 \(\beta\) = -0.97, CI = -3.41 – 1.38, P = 0.416
Exceed upper range Distribution overlap -0.89 -3.21 – 1.31 0.433 \(\beta\) = -0.89, CI = -3.21 – 1.31, P = 0.433
Exceed upper range Viable reciprocal hybrids 0.94 -1.35 – 3.2 0.403 \(\beta\) = 0.94, CI = -1.35 – 3.2, P = 0.403
Random effects estimates: insect data
Random effects Estimates 95% credible interval
Study.ID 5.97 0–31.8
Cross.ID 2.84 0–16.35
spL.name 30.36 0.18–119.64
SE.units 112.29 0.49–336.88
units 0.74 0.74–0.74
While one of significant moderators (Reciprocal hybrids) become no longer significant in insect subset data, effects are qualitatively the same in sign.

Effects of significant moderators

To visually interpret the impacts of significant moderators, we additionally conducted simpler models for each significant factor. As moderators, we included the focal factors, the compared parental species – spLL or spSS, and the interaction between them. Response variables and random effects of simper models were identical to full models.

# +++++++++++++++++++++++++++++++++++++++++++#
# To set raw metadata in X axis, reload raw metadata and combine to novelty dataset
# +++++++++++++++++++++++++++++++++++++++++++#
rawdat <- dat.full %>%
  select(-Pheno.divergence, -Genet.divergence) %>%
  # lnRR between parental species as phenotypic distance
  mutate(Pheno.divergence = log(Mn.spL/Mn.spS)) %>%
  left_join(
    .,
    read.xlsx("../data/original.data.xlsx", sheet = "Species.level.moderators") %>%
      select(Cross.ID, Genet.divergence)
    ) %>%
  # Natural log of genetic distance
  mutate_at("Genet.divergence", log) %>%
  mutate_at("direction", as.factor)

# +++++++++++++++++++++++++++++++++++++++++++#
# Regression: Genetic distance
# +++++++++++++++++++++++++++++++++++++++++++#

# ## Setting prior to logistic regression ###
# prior <- list(
#   B=list(
#     mu = rep(0, 3), # N of coefficient. (level -1) for categorical factors, 1 for continuous factors, 1 for intercept
#     V = gelman.prior(~ direction:Genet.divergence + Genet.divergence,
#     data = rawdat, # formula and data
#     scale=sqrt(pi^2/3+1))), # error distribution of logistic regression
#   R=list(V=1,fix=1),
#   G = list(
#     G1 = list(V = 1, nu = 1, alpha.mu = 0, alpha.V = 1000),
#     G2 = list(V = 1, nu = 1, alpha.mu = 0, alpha.V = 1000),
#     G3 = list(V = 1, nu = 1, alpha.mu = 0, alpha.V = 1000),
#     G4 = list(V = 1, nu = 1, alpha.mu = 0, alpha.V = 1000)
#     )
#   )
# ## Phylogenetic binomial regression ###
# phylmix <-MCMCglmm(
#   fixed = Novelty ~ direction:Genet.divergence + Genet.divergence,
#   # idh(SE):units | weight by SE of effect size
#   random = ~ Study.ID + Cross.ID + spL.name + idh(SE):units,
#   family = "categorical",
#   verbose = FALSE,
#   ginverse = list(spL.name = phylo_MCMC),
#   prior = prior,
#   data = rawdat,
#   nitt = 60000,  # Increase the number of iterations, default is 13000
#   burnin = 5000  # Increase the number of burnin, default is 3000
# )
# phylmix$Sol <- phylmix$Sol/sqrt(1+c2)
# ## Save model ###
# saveRDS(phylmix, file ="../Analysis/Mean.novelty.Genet.divergence.obj")

# +++++++++++++++++++++++++++++++++++++++++++#
# Regression: Phenotypic divergence
# +++++++++++++++++++++++++++++++++++++++++++#
# ## Setting prior to logistic regression ###
# prior <- list(
#   B=list(
#     mu = rep(0, 3), # N of coefficient. (level -1) for categorical factors, 1 for continuous factors, 1 for intercept
#     V = gelman.prior(~ direction:Pheno.divergence + Pheno.divergence,
#     data = rawdat, # formula and data
#     scale=sqrt(pi^2/3+1))), # error distribution of logistic regression
#   R=list(V=1,fix=1),
#   G = list(
#     G1 = list(V = 1, nu = 1, alpha.mu = 0, alpha.V = 1000),
#     G2 = list(V = 1, nu = 1, alpha.mu = 0, alpha.V = 1000),
#     G3 = list(V = 1, nu = 1, alpha.mu = 0, alpha.V = 1000),
#     G4 = list(V = 1, nu = 1, alpha.mu = 0, alpha.V = 1000)
#     )
#   )
# ## Phylogenetic binomial regression ###
# phylmix <-MCMCglmm(
#   fixed = Novelty ~ direction:Pheno.divergence + Pheno.divergence,
#   # idh(SE):units | weight by SE of effect size
#   random = ~ Study.ID + Cross.ID + spL.name + idh(SE):units,
#   family = "categorical",
#   verbose = FALSE,
#   ginverse = list(spL.name = phylo_MCMC),
#   prior = prior,
#   data = rawdat,
#   nitt = 60000,  # Increase the number of iterations, default is 13000
#   burnin = 5000  # Increase the number of burnin, default is 3000
# )
# phylmix$Sol <- phylmix$Sol/sqrt(1+c2)
# ## Save model ###
# saveRDS(phylmix, file ="../Analysis/Mean.novelty.Pheno.divergence.obj")

#++++++++++++++++++++++++++++++++++++++++++++++++++#
# Plot
#++++++++++++++++++++++++++++++++++++++++++++++++++#
for (i in c("Genet.divergence", "Pheno.divergence")) {
  
  ## Load model ###
  phylmix <- readRDS(
    paste("../Analysis/Mean.novelty",i, "obj", sep = ".")
    )
  reg <- summary(phylmix$Sol)$statistics %>%
      as.data.frame()
  
  ## Plot ###
  plot <- ggplot(rawdat, aes(x = rawdat[,i], y = rawdat[, "Novelty"])) +
    geom_jitter(
      height = 0.1, width = 0, aes(color = direction), alpha = 0.3, size = 0.2
      ) +
    # novelty for larger mean
    stat_function(
      aes(color = "+"), size = 0.8,
      fun = function(x) 
        1/(1 + exp(-(reg[1,1] + x*(reg[2,1]+reg[3,1]))))
      ) +
    # novelty for smaller mean
    stat_function(
      aes(color = "-"), size = 0.8,
      fun = function(x) 
        1/(1 + exp(-(reg[1,1] + x*reg[2,1])))
      ) +
    ylab("Novelty in phenotypic means") + 
    xlab(paste(i, "(log)")) +
    scale_fill_brewer(palette = "Set2") +
    scale_y_continuous(breaks=seq(0,1)) +
    regressiontheme 
  print(plot)
  # ggsave(
  #   plot = plot + theme(axis.title  = element_blank()),
  #   file = paste("../Analysis/mean.TS.continuous", i, "svg", sep = "."),
  #   height = 1.6, width = 1.7
  #   )

}

for (i in c("Reciprocal", "trait.type")) {

    # Make new categorical data combining direction of TS and target categorical factor
    dat %<>%
      mutate(interaction = str_c(direction, .[, i], sep = "_"))
    
    # ## Setting prior to logistic regression ###
    # prior <- list(
    #   B=list(
    #     mu = rep(0, 4), # N of coefficient. (level -1) for categorical factors, 1 for continuous factors, 1 for intercept
    #     V = gelman.prior(~ interaction, # + trait.direction
    #     data = dat, # formula and data
    #     scale=sqrt(pi^2/3+1))), # error distribution of logistic regression
    #   R=list(V=1,fix=1),
    #   # Replicating same G for the number of random effects (here, 4)
    #   G = list(
    #     G1 = list(V = 1, nu = 1, alpha.mu = 0, alpha.V = 1000),
    #     G2 = list(V = 1, nu = 1, alpha.mu = 0, alpha.V = 1000),
    #     G3 = list(V = 1, nu = 1, alpha.mu = 0, alpha.V = 1000),
    #     G4 = list(V = 1, nu = 1, alpha.mu = 0, alpha.V = 1000)
    #     )
    #   )
    # 
    # phylmix <-MCMCglmm(
    #   fixed = Novelty ~  interaction -1, # + trait.direction
    #   family = "categorical",
    #   # idh(SE):units | weight by SE of effect size
    #   random = ~ Study.ID + Cross.ID + spL.name + idh(SE):units,
    #   verbose = FALSE,
    #   ginverse = list(spL.name = phylo_MCMC),
    #   prior = prior,
    #   data = dat
    # )
    # # Correct model result
    # phylmix$Sol <- phylmix$Sol/sqrt(1+c2)
    # ## Save model ###
    # saveRDS(
    #   phylmix,
    #   file =
    #     paste("../Analysis/Mean.novelty", i, "alltaxon.obj", sep = ".")
    #     )

  #++++++++++++++++++++++++++++++++++++++#  
  # ing interaction terms
  #++++++++++++++++++++++++++++++++++++++#
  phylmix <- readRDS(
    paste("../Analysis/Mean.novelty", i, "alltaxon.obj", sep = ".")
    )
  
  sum <- summary(phylmix)$solutions %>%
    as.data.frame() %>%
    rownames_to_column(var = "factors") %>%
    mutate(
      # Impact on exceeding upper or lower range
      direction =
        ifelse(str_detect(factors, "interaction\\+"), 
               "Exceed upper range",
               "Exceed lower range"
               ) %>%
        as.factor
      ) %>%
    within(direction <- ordered(direction, c("Exceed upper range", "Exceed lower range"))) %>%
    ## Change factor names ###
    within(
      factors <- str_remove_all(factors, "interaction._")
      )       
  
    #++++++++++++++++++++++++++++++++++++++#  
    # Plot
    #++++++++++++++++++++++++++++++++++++++#
    categoricalplot <- ggplot(sum, aes(x = post.mean, y = factors)) +
      # Vertical line
      geom_vline(
        xintercept = 0, size = 0.3,
        colour = "grey30", linetype = "dotted"
        ) +
      # CI
      geom_errorbarh(
        aes(xmin = sum[, 'l-95% CI'], xmax = sum[, 'u-95% CI']),
        height = .0001
        ) +
      geom_point(size = 1.3, shape = 17) +
      # Title
      ylab("") + xlab("Effect on novelty in phenotypic means") +
      ggtitle(i) +
      # Combine different plots for main factors and interactions
      facet_grid(
        direction ~., scales = "free", drop = TRUE,
        labeller = label_wrap_gen(width = 11)
        ) +
      foresttheme
    print(categoricalplot)
  
    # ggsave(
    #     plot = categoricalplot + theme(axis.text.y = element_blank()),
    #     file = paste("../Analysis/Mean.TS.categorical", i,taxon, "svg", sep = "."),
    #     height = 1.8, width = 2.5
    #     )

}

Novelty in phenotypic variabilities (using CV)

Frequency

dat.full <- read.csv("../data/variation.ES.Novelty.csv", head = TRUE)

## N of TS in each taxa and each direction ###
summary <- bind_rows(
  # All observations
  dat.full %>%
    group_by(taxa) %>%
    summarise(
      'Species pair' = length(unique(species.pair)),
      Observations = length(unique(ES.ID)),
      Study = length(unique(Study.ID))
      ) %>%
    mutate(direction = "All Observations")
  ,
  # TS for any direction
  dat.full %>%
    filter(Novelty == "1") %>%
    group_by(taxa) %>%
    summarise(
      'Species pair' = length(unique(species.pair)),
      Observations = length(unique(ES.ID)),
      Study = length(unique(Study.ID))
      ) %>%
    mutate(direction = "Increase novelty")
  ,
  # TS for each direction
  dat.full %>%
    filter(Novelty == "1") %>%
    group_by(taxa, direction) %>%
    summarise(
      'Species pair' = length(unique(species.pair)),
      Observations = length(unique(ES.ID)),
      Study = length(unique(Study.ID))
      )
  ) %>%
  # Assign 0 for no observation of TS
  replace(., is.na(.), "0") %>% 
  # Make tidy data
  gather(key = metrics, value = N, -c(taxa, direction)) %>%
  # Order factors
  mutate_at(vars("metrics", "direction"), as.factor) %>%
  filter(metrics != "Study")

# Order taxon
summary$metrics <- ordered(summary$metrics, levels = c("Study", "Species pair", "Observations"))
# Order TS category
summary$direction <- ordered(summary$direction, levels = c("All Observations", "Increase novelty", "+", "-"))
# Change names of TS category to more intuitive name
levels(summary$direction) <- c("All Observations", "Increase novelty", "Exceed upper range", "Exceed lower range")

## Plot ###
plot <- ggplot(
  # rename levels of factors to wrap label text
  summary %>%
    within(levels(direction) <- c("All Obser- vations", "Novel phenotypic variabilities", "Exceed upper range", "Exceed lower range")) %>%
    within(levels(metrics) <- c("Study", "Species pair", "Obser- vations")), 
  aes(x = "", y = N, fill = taxa)) +
  geom_bar(width = 1, stat = "identity") +
  scale_fill_brewer(palette = "Paired") +
  facet_grid(
    scale = "free", metrics ~ direction,
    # strip text into two lines
    labeller = label_wrap_gen(width = 10)
    ) +
  xlab("") + ylab("") +
  stackedbartheme
plot +
  ggtitle("Taxonomic distribution of novel phenotypic variabilities")

# ggsave(
#   plot = plot,
#   file = "../Analysis/Variation.TS.frequency.svg", height = 3.7, width = 5.0
#   )

## Total number of observations and percentage ###
summary %>%
  group_by(direction, metrics) %>%
  # Count number of observaitons and species pairs
  summarise(sum(N)) %>%
  spread(key = metrics, value = "sum(N)") %>%
  as.data.frame() %>%
  # Calculate percentage
  mutate(
    'Species pair %' = .[, "Species pair"]/.[1, "Species pair"]*100,
    'Observaton %' = Observations/.[1, "Observations"]*100
  ) %>%
  mutate_at(vars(contains("percent")), round, 2) %>%
  kable("html", digits = 3, caption = "Summary of the novel phenotypic variabilities frequency") %>% 
  kable_styling("striped", position = "left")
Summary of the novel phenotypic variabilities frequency
direction Species pair Observations Species pair % Observaton %
All Observations 33 331 100.000 100.000
Increase novelty 31 248 93.939 74.924
Exceed upper range 18 82 54.545 24.773
Exceed lower range 26 170 78.788 51.360

Factors affecting novelty in phenotypic variability

We checked robustness of results by conducting identical analysis for insect subset data (removing vertebrate data).

Model, which was ran using MCMCglmm function, included following Random effects estimates:

  • Study.ID: Primary studies

  • Cross.ID: Parental strain used in the crossing. Discriminate intraspecific populations

  • spL.name: Phylogeny of parental species (spLLV)

  • SE.units: Sampling variance of effect size

The moderators were categorised into 3 subsets: main effects (labelled as novelty in phenotypic variabilities), interaction terms with compared parental species (spLL vs. spSS, labelled as exceed upper range; mother species vs. father, labelled as exceed mother).

#++++++++++++++++++++++++++++++++++#
# Phylogenetic tree for mcmcglmm 
#++++++++++++++++++++++++++++++++++#

# compute branch lengths of tree
phylo_branch <- read.tree(file = "../data/phylo.variation.tre") %>%
  compute.brlen(method = "Grafen", power = 1)

# saving phylogeneic matrix
phylo_cor <- vcv(phylo_branch, cor = T)

# generating inverse phylogenetic matrix for MCMCglmm
phylo_branch$node.label <- NULL
phylo_MCMC <- MCMCglmm::inverseA(phylo_branch, nodes = "ALL", scale = TRUE)$Ainv


#+++++++++++++++++++++++++++++++++++++#
# Phylogenetic comparative analysis
#+++++++++++++++++++++++++++++++++++++#

# Caption
cap <- data.frame(
  desc = c(
    "Table S8. Fixed effects estimates of Bayesian logistic model investigating factors affecting novelty in phenotypic variabilities. Data of all taxon was used",
    "Fixed effects estimates: insect subset data"
    )
  ) %>%
  mutate_all(as.character)
row.names(cap) <- c("alltaxon", "insect")

for (taxon in c("alltaxon", "insect")) {
  
  if (taxon == "alltaxon") {
    dat <- dat.full
  } else {
    dat <- dat.full %>% 
      filter(insect == taxon)
  }
  
  # ## Setting prior to logistic regression ###
  # prior <- list(
  #   B=list(
  #     mu = rep(0, 17), # N of coefficient. (level -1) for categorical factors, 1 for continuous factors, 1 for intercept
  #     V = gelman.prior(~
  #     parental*Hetero.sex + parental*direction +
  #     direction*Genet.divergence + direction*Pheno.divergence +
  #     direction*Hetero.sex + direction*trait.type +
  #     direction*Distribution + direction*Reciprocal,
  #     data = dat, # formula and data
  #     scale=sqrt(pi^2/3+1))), # error distribution of logistic regression
  #   R=list(V=1,fix=1),
  #   # Replicating same G for the number of random effects (here, 4)
  #   G = list(
  #     G1 = list(V = 1, nu = 1, alpha.mu = 0, alpha.V = 1000),
  #     G2 = list(V = 1, nu = 1, alpha.mu = 0, alpha.V = 1000),
  #     G3 = list(V = 1, nu = 1, alpha.mu = 0, alpha.V = 1000),
  #     G4 = list(V = 1, nu = 1, alpha.mu = 0, alpha.V = 1000)
  #     )
  #   )
  # ## Phylogenetic binomial regression ###
  # phylmix <-MCMCglmm(
  #   fixed = Novelty ~
  #     parental*Hetero.sex + parental*direction +
  #     direction*Genet.divergence + direction*Pheno.divergence +
  #     direction*Hetero.sex + direction*trait.type +
  #     direction*Distribution + direction*Reciprocal,
  #   family = "categorical",
  #   # idh(SE):units | weight by SE of effect size
  #   random = ~ Study.ID + Cross.ID + spL.name + idh(SE):units,
  #   verbose = FALSE,
  #   ginverse = list(spL.name = phylo_MCMC),
  #   prior = prior,
  #   data = dat,
  #   nitt = 60000,  # Increase the number of iterations, default is 13000
  #   burnin = 5000  # Increase the number of burnin, default is 3000
  # )
  # ## Correcting estimate ###
  # phylmix$Sol <- phylmix$Sol/sqrt(1+c2)
  # ## Save model ###
  # saveRDS(
  #   phylmix,
  #   file = paste("../Analysis/Variation.novelty.allfactors", taxon, "obj", sep = ".")
  #   )
  
  ## Load model ###
  phylmix <- readRDS(file = paste("../Analysis/Variation.novelty.allfactors", taxon, "obj", sep = "."))
  
  sum <- get_fixed.MCMCglmm(summary(phylmix)$solutions) %>%
    ## ing Factors ###
    mutate(
      Group = 
        ifelse(str_detect(Factors, "direction.:"), 
               "Exceed upper range",
               ifelse(str_detect(Factors, "parentalMother:"),
                      "Exceed mother",
                      ifelse(Factors == "Hetero.sexMale:direction+",
                             "Exceed upper range",
                             "Increase novelty"
                             )
                      )
               )
    ) %>%
    mutate_at("Group", as.factor) %>%
    within(Group <- ordered(Group, c("Increase novelty", "Exceed upper range", "Exceed mother"))) %>%
    ## Change factor names ###
    within(
      Factors <- str_remove_all(
        Factors, "direction.:"
        ) %>%
        str_remove_all(., "parentalMother:") %>%
        str_remove_all(., ":direction.")
      ) %>%
    within(
      Factors <- factor(
        Factors, ordered = TRUE, 
        levels = c("parentalMother", "direction+", "trait.typesound", "Hetero.sexMale", "ReciprocalViable", "DistributionOverlap", "Pheno.divergence",  "Genet.divergence",  "(Intercept)")
        )
      )
  levels(sum$Factors) <- c("Exceed mother", "Exceed upper range", "Sound traits", "Male heterogametic", "Viable reciprocal hybrids", "Distribution overlap", "Phenotypic divergence", "Genetic divergence", "Intercept")
  
  ## Plot ###
  metaplot <- ggplot(sum, aes(x = post.mean, y = Factors)) +
    # Vertical line
    geom_vline(
      xintercept = 0, size = 0.2, 
      colour = "grey30", linetype = "dotted"         
      ) +
    # CI
    geom_errorbarh(
      aes(
        xmin = sum[, 'l-95% CI'], xmax = sum[, 'u-95% CI'],
        colour=significance 
        ), 
      height = .0001
      ) +
    # Color of plots and errorbars
    scale_colour_manual(values = c("grey60", "black")) +
    geom_point(size = 1, aes(colour = significance)) +
    scale_fill_manual(values = c("grey60", "black")) +
    # Title
    ggtitle(paste("Fixed effects estimates using", taxon, "data")) +
    ylab("") + xlab("Estimate with 95% CI") +
    # Combine different plots for main Factors and interactions
    facet_grid(
      Group~., scales = "free", space = "free",
      labeller = label_wrap_gen(width = 20)
      ) +
    # Themes
    foresttheme
  print(metaplot)
  
  # ggsave(
  #     plot = metaplot, 
  #     file = paste("../Analysis/variation.TS.result", taxon, "svg", sep = "."), 
  #     height = 4.7, width = 4.0
  #     )
  
  #+++++++++++++++++++++++++#
  # Fixed effects output
  #+++++++++++++++++++++++++#
  sum %>% 
    select(Group, Factors, Estimates, '95% credible interval', P, significance, Description) %>%
    kable("html", caption = cap[taxon,]) %>% 
    kable_styling("striped", position = "left") %>%
    scroll_box(width = "100%", height = "500px") %>%
    print()
  
  #+++++++++++++++++++++++++++#
  # Random effects output 
  #+++++++++++++++++++++++++++#
  # transformation for varaince
  get_random.MCMCglmm(summary(phylmix$VCV/(1+c2))) %>%
    kable("html", digits = 2,
          caption = paste("Random effects estimates: ", taxon, "data", " ")
          ) %>% 
    kable_styling("striped", position = "left") %>%
    print()
  
}
Table S8. Fixed effects estimates of Bayesian logistic model investigating factors affecting novelty in phenotypic variabilities. Data of all taxon was used
Group Factors Estimates 95% credible interval P significance Description
Increase novelty Intercept -0.41 -3.57 – 3.2 0.769 \(\beta\) = -0.41, CI = -3.57 – 3.2, P = 0.769
Increase novelty Exceed mother 0.54 -1.43 – 2.43 0.588 \(\beta\) = 0.54, CI = -1.43 – 2.43, P = 0.588
Increase novelty Male heterogametic -0.06 -2.68 – 2.33 0.961 \(\beta\) = -0.06, CI = -2.68 – 2.33, P = 0.961
Increase novelty Exceed upper range -1.36 -3.52 – 0.78 0.210 \(\beta\) = -1.36, CI = -3.52 – 0.78, P = 0.21
Increase novelty Genetic divergence -0.47 -1.23 – 0.26 0.220 \(\beta\) = -0.47, CI = -1.23 – 0.26, P = 0.22
Increase novelty Phenotypic divergence -0.39 -1.02 – 0.2 0.208 \(\beta\) = -0.39, CI = -1.02 – 0.2, P = 0.208
Increase novelty Sound traits 1.68 -0.31 – 3.83 0.109 \(\beta\) = 1.68, CI = -0.31 – 3.83, P = 0.109
Increase novelty Distribution overlap -0.69 -2.55 – 1.26 0.464 \(\beta\) = -0.69, CI = -2.55 – 1.26, P = 0.464
Increase novelty Viable reciprocal hybrids -1.07 -2.72 – 0.62 0.203 \(\beta\) = -1.07, CI = -2.72 – 0.62, P = 0.203
Exceed mother Male heterogametic -1.44 -3.45 – 0.43 0.142 \(\beta\) = -1.44, CI = -3.45 – 0.43, P = 0.142
Exceed mother Exceed upper range -0.22 -1.7 – 1.33 0.790 \(\beta\) = -0.22, CI = -1.7 – 1.33, P = 0.79
Exceed upper range Genetic divergence 1.25 0.47 – 2 0.000
\(\beta\) = 1.25, CI = 0.47 – 2, P = 0
Exceed upper range Phenotypic divergence 0.83 0.01 – 1.61 0.036
\(\beta\) = 0.83, CI = 0.01 – 1.61, P = 0.036
Exceed upper range Male heterogametic 0.47 -1.84 – 2.7 0.678 \(\beta\) = 0.47, CI = -1.84 – 2.7, P = 0.678
Exceed upper range Sound traits -3.29 -5.21 – -1.38 0.001
\(\beta\) = -3.29, CI = -5.21 – -1.38, P = 0.001
Exceed upper range Distribution overlap 1.32 -0.53 – 3.08 0.151 \(\beta\) = 1.32, CI = -0.53 – 3.08, P = 0.151
Exceed upper range Viable reciprocal hybrids 1.19 -0.55 – 2.98 0.177 \(\beta\) = 1.19, CI = -0.55 – 2.98, P = 0.177
Random effects estimates: alltaxon data
Random effects Estimates 95% credible interval
Study.ID 2.07 0.02–7.41
Cross.ID 0.53 0–2.78
spL.name 2.54 0–13.9
SE.units 92.08 37.22–172.67
units 0.74 0.74–0.74
Fixed effects estimates: insect subset data
Group Factors Estimates 95% credible interval P significance Description
Increase novelty Intercept -0.22 -5.65 – 5.45 0.912 \(\beta\) = -0.22, CI = -5.65 – 5.45, P = 0.912
Increase novelty Exceed mother 0.62 -1.83 – 3 0.627 \(\beta\) = 0.62, CI = -1.83 – 3, P = 0.627
Increase novelty Male heterogametic 0.04 -3.13 – 3.38 0.965 \(\beta\) = 0.04, CI = -3.13 – 3.38, P = 0.965
Increase novelty Exceed upper range -1.14 -3.82 – 1.56 0.403 \(\beta\) = -1.14, CI = -3.82 – 1.56, P = 0.403
Increase novelty Genetic divergence -0.14 -1.09 – 0.93 0.777 \(\beta\) = -0.14, CI = -1.09 – 0.93, P = 0.777
Increase novelty Phenotypic divergence -0.41 -1.39 – 0.57 0.408 \(\beta\) = -0.41, CI = -1.39 – 0.57, P = 0.408
Increase novelty Sound traits 0.78 -2.25 – 3.69 0.586 \(\beta\) = 0.78, CI = -2.25 – 3.69, P = 0.586
Increase novelty Distribution overlap -0.57 -3.54 – 2.24 0.695 \(\beta\) = -0.57, CI = -3.54 – 2.24, P = 0.695
Increase novelty Viable reciprocal hybrids -0.78 -3.2 – 1.82 0.527 \(\beta\) = -0.78, CI = -3.2 – 1.82, P = 0.527
Exceed mother Male heterogametic -0.55 -3.03 – 1.94 0.677 \(\beta\) = -0.55, CI = -3.03 – 1.94, P = 0.677
Exceed mother Exceed upper range 0.25 -2.25 – 2.62 0.842 \(\beta\) = 0.25, CI = -2.25 – 2.62, P = 0.842
Exceed upper range Genetic divergence 0.83 -0.1 – 1.78 0.085 \(\beta\) = 0.83, CI = -0.1 – 1.78, P = 0.085
Exceed upper range Phenotypic divergence 1.04 -0.1 – 2.15 0.067 \(\beta\) = 1.04, CI = -0.1 – 2.15, P = 0.067
Exceed upper range Male heterogametic -0.21 -3.07 – 2.59 0.896 \(\beta\) = -0.21, CI = -3.07 – 2.59, P = 0.896
Exceed upper range Sound traits -2.45 -4.95 – 0.41 0.079 \(\beta\) = -2.45, CI = -4.95 – 0.41, P = 0.079
Exceed upper range Distribution overlap 0.79 -1.78 – 3.36 0.544 \(\beta\) = 0.79, CI = -1.78 – 3.36, P = 0.544
Exceed upper range Viable reciprocal hybrids 0.03 -2.76 – 2.69 0.975 \(\beta\) = 0.03, CI = -2.76 – 2.69, P = 0.975
Random effects estimates: insect data
Random effects Estimates 95% credible interval
Study.ID 13.88 0.36–51.78
Cross.ID 1.68 0–8.89
spL.name 18.74 0.08–74.21
SE.units 565.34 123.22–1224.95
units 0.74 0.74–0.74
While significant moderators become no longer significant in insect subset data, effects are qualitatively the same in sign.

Effects of significant moderators

To visually interpret the impacts of significant moderators, we additionally conducted simpler models for each significant factor. As moderators, we included the focal factors, the compared parental species – spLL or spSS, and the interaction between them. Response variables and random effects of simper models were identical to full models.

# +++++++++++++++++++++++++++++++++++++++++++#
# To set raw metadata in X axis, reload raw metadata and combine to transgression dataset
# +++++++++++++++++++++++++++++++++++++++++++#
rawdat <- dat.full %>%
  select(-Pheno.divergence, -Genet.divergence) %>%
  # lnRR between parental species as phenotypic distance
  mutate(Pheno.divergence = abs(log(Mn.spL/Mn.spS))) %>%
  left_join(
    .,
    read.xlsx("../data/original.data.xlsx", sheet = "Species.level.moderators") %>%
      select(Cross.ID, Genet.divergence)
    ) %>%
  # Natural log of genetic distance
  mutate_at("Genet.divergence", log)

# # +++++++++++++++++++++++++++++++++++++++++++#
# # Regression: Genetic distance
# # +++++++++++++++++++++++++++++++++++++++++++#
# 
# ## Setting prior to logistic regression ###
# prior <- list(
#   B=list(
#     mu = rep(0, 3), # N of coefficient. (level -1) for categorical factors, 1 for continuous factors, 1 for intercept
#     V = gelman.prior(~ direction:Genet.divergence + Genet.divergence,
#     data = rawdat, # formula and data
#     scale=sqrt(pi^2/3+1))), # error distribution of logistic regression
#   R=list(V=1,fix=1),
#   G = list(
#     G1 = list(V = 1, nu = 1, alpha.mu = 0, alpha.V = 1000),
#     G2 = list(V = 1, nu = 1, alpha.mu = 0, alpha.V = 1000),
#     G3 = list(V = 1, nu = 1, alpha.mu = 0, alpha.V = 1000),
#     G4 = list(V = 1, nu = 1, alpha.mu = 0, alpha.V = 1000)
#     )
#   )
# ## Phylogenetic binomial regression ###
# phylmix <-MCMCglmm(
#   fixed = Novelty ~ direction:Genet.divergence + Genet.divergence,
#   # idh(SE):units | weight by SE of effect size
#   random = ~ Study.ID + Cross.ID + spL.name + idh(SE):units,
#   family = "categorical",
#   verbose = FALSE,
#   ginverse = list(spL.name = phylo_MCMC),
#   prior = prior,
#   data = rawdat,
#   nitt = 60000,  # Increase the number of iterations, default is 13000
#   burnin = 5000  # Increase the number of burnin, default is 3000
# )
# phylmix$Sol <- phylmix$Sol/sqrt(1+c2)
# ## Save model ###
# saveRDS(phylmix, file ="../Analysis/Variation.novelty.Genet.divergence.obj")
# 
# # +++++++++++++++++++++++++++++++++++++++++++#
# # Regression: Phenotypic divergence
# # +++++++++++++++++++++++++++++++++++++++++++#
# 
# ## Setting prior to logistic regression ###
# prior <- list(
#   B=list(
#     mu = rep(0, 3), # N of coefficient. (level -1) for categorical factors, 1 for continuous factors, 1 for intercept
#     V = gelman.prior(~ direction:Pheno.divergence + Pheno.divergence,
#     data = rawdat, # formula and data
#     scale=sqrt(pi^2/3+1))), # error distribution of logistic regression
#   R=list(V=1,fix=1),
#   G = list(
#     G1 = list(V = 1, nu = 1, alpha.mu = 0, alpha.V = 1000),
#     G2 = list(V = 1, nu = 1, alpha.mu = 0, alpha.V = 1000),
#     G3 = list(V = 1, nu = 1, alpha.mu = 0, alpha.V = 1000),
#     G4 = list(V = 1, nu = 1, alpha.mu = 0, alpha.V = 1000)
#     )
#   )
# ## Phylogenetic binomial regression ###
# phylmix <-MCMCglmm(
#   fixed = Novelty ~ direction:Pheno.divergence + Pheno.divergence,
#   # idh(SE):units | weight by SE of effect size
#   random = ~ Study.ID + Cross.ID + spL.name + idh(SE):units,
#   family = "categorical",
#   verbose = FALSE,
#   ginverse = list(spL.name = phylo_MCMC),
#   prior = prior,
#   data = rawdat,
#   nitt = 60000,  # Increase the number of iterations, default is 13000
#   burnin = 5000  # Increase the number of burnin, default is 3000
# )
# phylmix$Sol <- phylmix$Sol/sqrt(1+c2)
# ## Save model ###
# saveRDS(phylmix, file ="../Analysis/Variation.novelty.Pheno.divergence.obj")

#++++++++++++++++++++++++++++++++++++++++++++++++++#
# Plot
#++++++++++++++++++++++++++++++++++++++++++++++++++#

for (i in c("Genet.divergence", "Pheno.divergence")) {
  
  ## Load model ###
  phylmix <- readRDS(
    paste("../Analysis/Variation.novelty",i, "obj", sep = ".")
    )
  reg <- summary(phylmix$Sol)$statistics %>%
      as.data.frame()
  
  ## Plot ###
  plot <- ggplot(rawdat, aes(x = rawdat[,i], y = rawdat[, "Novelty"])) +
    geom_jitter(
      height = 0.1, width = 0, aes(color = direction), alpha = 0.3, size = 0.2
      ) +
    # Larger variability
    stat_function(
      aes(color = "+"), size = 0.8,
      fun = function(x) 
        1/(1 + exp(-(reg[1,1] + x*(reg[2,1]+reg[3,1]))))
      ) +
    # Smaller variability
    stat_function(
      aes(color = "-"), size = 0.8,
      fun = function(x) 
        1/(1 + exp(-(reg[1,1] + x*reg[2,1])))
      ) +
    ylab("Novel phenotypic variabilities") + 
    xlab(paste(i, "(log)")) +
    scale_fill_brewer(palette = "Set2") +
    scale_y_continuous(breaks=seq(0,1)) +
    regressiontheme 
  
  print(plot)
  # ggsave(
  #   plot = plot, 
  #   file = paste("../Analysis/Variation.TS.continuous", i, "svg", sep = "."), 
  #   height = 1.6, width = 1.7
  #   )

}

for (i in c("Reciprocal", "trait.type")) {

  # Make new categorical data combining direction of TS and target categorical factor
  dat %<>%
    mutate(interaction = str_c(direction, .[, i], sep = "_"))

  # ## Setting prior to logistic regression ###
  # prior <- list(
  #   B=list(
  #     mu = rep(0, 4), # N of coefficient. (level -1) for categorical factors, 1 for continuous factors, 1 for intercept
  #     V = gelman.prior(~ interaction,
  #     data = dat, # formula and data
  #     scale=sqrt(pi^2/3+1))), # error distribution of logistic regression
  #   R=list(V=1,fix=1),
  #   # Replicating same G for the number of random effects (here, 4)
  #   G = list(
  #     G1 = list(V = 1, nu = 1, alpha.mu = 0, alpha.V = 1000),
  #     G2 = list(V = 1, nu = 1, alpha.mu = 0, alpha.V = 1000),
  #     G3 = list(V = 1, nu = 1, alpha.mu = 0, alpha.V = 1000),
  #     G4 = list(V = 1, nu = 1, alpha.mu = 0, alpha.V = 1000)
  #     )
  #   )
  # ## Run model ###
  # phylmix <-MCMCglmm(
  #   fixed = Novelty ~  interaction -1, # + trait.direction
  #   family = "categorical",
  #   # idh(SE):units | weight by SE of effect size
  #   random = ~ Study.ID + Cross.ID + spL.name + idh(SE):units,
  #   verbose = FALSE,
  #   ginverse = list(spL.name = phylo_MCMC),
  #   prior = prior,
  #   data = dat
  # )
  # # Correcting estimate
  # phylmix$Sol <- phylmix$Sol/sqrt(1+c2)
  # ## Save model ###
  # saveRDS(
  #   phylmix,
  #   file =
  #     paste("../Analysis/Variation.novelty", i, "alltaxon.obj", sep = ".")
  #     )
  
  #++++++++++++++++++++++++++++++++++++++#  
  # Grouping interaction terms
  #++++++++++++++++++++++++++++++++++++++#
  phylmix <- readRDS(
    paste("../Analysis/Variation.novelty", i, "alltaxon.obj", sep = ".")
    )
  
  sum <- summary(phylmix)$solutions %>%
    as.data.frame() %>%
    rownames_to_column(var = "factors") %>%
    mutate(
      # Impact on exceeding upper or lower range
      direction =
        ifelse(str_detect(factors, "interaction\\+"), 
               "Exceed upper range",
               "Exceed lower range"
               ) %>%
        as.factor
      ) %>%
    within(direction <- ordered(direction, c("Exceed upper range", "Exceed lower range"))) %>%
    ## Change factor names ###
    within(
      factors <- str_remove_all(factors, "interaction._")
      )       
  
    #++++++++++++++++++++++++++++++++++++++#  
    # Plot
    #++++++++++++++++++++++++++++++++++++++#
    categoricalplot <- ggplot(sum, aes(x = post.mean, y = factors)) +
      # Vertical line
      geom_vline(
        xintercept = 0, size = 0.3,
        colour = "grey30", linetype = "dotted"
        ) +
      # CI
      geom_errorbarh(
        aes(xmin = sum[, 'l-95% CI'], xmax = sum[, 'u-95% CI']),
        height = .0001
        ) +
      geom_point(size = 1.3, shape = 17) +
      # Title
      ylab("") + xlab("Effect on novelty in phenotypic means") +
      ggtitle(i) +
      # Combine different plots for main factors and interactions
      facet_grid(
        direction ~., scales = "free", drop = TRUE,
        labeller = label_wrap_gen(width = 11)
        ) +
      foresttheme
    print(categoricalplot)
  
  # ggsave(
  #     plot = categoricalplot + theme(axis.text.y = element_blank()),
  #     file = 
  #       paste("../Analysis/Variation.novelty.categorical", i,taxon, "svg", sep = "."),
  #     height = 1.8, width = 2.5
  #     )
  
}

Phenotypic variability of novel phenotype

Dataset summary

Relative variability indicates F1 hybrids’ phenotypic variability size (CV) compared to those of parents.

  • Smaller: smaller variability than of both parents

  • Intermediate: intermediate between parents’ variability

  • Larger: larger variability than of both parents

dat <- read.csv("../data/dat.novelty.csv", head = TRUE) %>% 
  mutate_at(vars("mean.novelty", "relative.var"), as.factor) %>% 
  within(
    relative.var <-
      ordered(relative.var, levels = c("Smaller", "Intermediate", "Larger")),
    mean.novelty <- 
      ordered(mean.novelty, levels = c("Nonnovel", "Novel"))
  )

dat.relat.var <- dat %>% 
  group_by(mean.novelty, relative.var) %>% 
  summarise('N (Trait observation)' = length(ES.ID)) %>% 
  spread(key = mean.novelty, value = 'N (Trait observation)') %>%
  as.data.frame() %>%
  mutate(
    "Nonnovel phenotype (% trait obs)" = 
      Nonnovel/sum(Nonnovel)*100, 
    "Novel phenotype (% trait obs)" = 
      Novel/sum(Novel)*100,
    Trait.count = Nonnovel + Novel # N of traits at each variability levels
  ) %>%
  rename('Relative.variability' = 'relative.var')

ggplot(
  dat.relat.var %>%
    dplyr::select(-contains("trait obs"), -Trait.count) %>%
    pivot_longer(
      col = -Relative.variability,
      names_to = "Phenotypic.novelty",
      values_to = "Count"
      ) %>%
    left_join(dat.relat.var) %>%
    as.data.frame %>%
    mutate_at("Phenotypic.novelty", as.factor),
  aes(
    y = Count, 
    x = Trait.count/2,  # ensure each pie chart is "left-aligned"
    width = Trait.count, # sample size (N of traits at each variability levels)
    fill = Phenotypic.novelty
    )
  ) +
  geom_bar(position="fill", stat = "identity") +
  facet_grid(~ Relative.variability) +
  # Pie chart
  coord_polar("y") +
  ggtitle("Novel and non-novel phenotypes occupancies at
          each relative variability levels") +
  xlab("Trait counts") + ylab("Relative variability levels") +
  theme(axis.text.x = element_blank())

dat.relat.var %>%
  rename(
  'Nonnovel.phenotype (N)' = 'Nonnovel',
  'Novel.phenotype (N)' = 'Novel'
  ) %>%
  kable("html", digits = 1, caption = "Dataset summary") %>%
  kable_styling("striped", position = "left")
Dataset summary
Relative.variability Nonnovel.phenotype (N) Novel.phenotype (N) Nonnovel phenotype (% trait obs) Novel phenotype (% trait obs) Trait.count
Smaller 146 74 49.2 40.4 220
Intermediate 96 54 32.3 29.5 150
Larger 55 55 18.5 30.1 110
#++++++++++++++++++++++++++++++++++++++++++++++++++++++#
# Read create tree based on Open Tree of Life taxonomy
#++++++++++++++++++++++++++++++++++++++++++++++++++++++#

# # matching names from open tree taxonomy
# taxa <- tnrs_match_names(
#   names = levels(dat$sp1.name) %>%
#     str_replace_all("_", " "),
#   context_name = "Animals"
#   )
# 
# # Create tree
# tree <- tol_induced_subtree(ott_ids = taxa$ott_id)
# tree$tip.label %<>%
#   strip_ott_ids # remove OTT IDs from tip labels
# # randomly solve non-binary phylogeny
# set.seed(6)
# bin.tree <- multi2di(tree, random = T)
# print("Randomly solved phylogeny")
# 
# # Indicate mismatch between tip labels & dataset species names
# setdiff(levels(as.factor(bin.tree$tip.label)), levels(dat$sp1.name))
# setdiff(levels(dat$sp1.name), levels(as.factor(bin.tree$tip.label)))
# # Fix names of tip labels
# bin.tree$tip.label %<>% str_replace_all("Dryophytes", "Hyla")
# 
# write.tree(bin.tree, file= "../data/phylo.novelty.tre")

#++++++++++++++++++++++++++++++++++#
# Phylogenetic tree for mcmcglmm 
#++++++++++++++++++++++++++++++++++#

# compute branch lengths of tree
phylo_branch <- read.tree(file = "../data/phylo.novelty.tre") %>%
  compute.brlen(method = "Grafen", power = 1)
plot.phylo(phylo_branch, cex = 0.7)
Figure S3. Phylogenetic tree used, which was based on tree of the parental species within a cross which name comes earlier in alphabetical order

Figure S3. Phylogenetic tree used, which was based on tree of the parental species within a cross which name comes earlier in alphabetical order

# saving phylogeneic matrix
phylo_cor <- vcv(phylo_branch, cor = T)

# generating inverse phylogenetic matrix for MCMCglmm
phylo_branch$node.label <- NULL
phylo_MCMC <- MCMCglmm::inverseA(phylo_branch, nodes = "ALL", scale = TRUE)$Ainv

Phylogenetic ordinal (probit) regression

Here we ask if phenotypic novelty associate with relative variability levels. We conducted ordinal regression, employing categorical ordered variability levels (smaller < intermediate < larger, see above) as response variable, and categorical trait mean novelty levels (fixed effect mean.novelty with 2 levels: Novel vs Nonnovel) as moderator variable, using MCMCglmm function. The model included following Random effects estimates:

  • Study.ID: Primary studies

  • sp1.name: Phylogeny of parental species

  • Cross.ID: Parental strain used in the crossing. Discriminate intraspecific populations

  • cross: Crossing direction

  • SE.units: Sampling variance of effect size

# prior1<-list(
#   B=list(
#     mu=c(0,0),
#     V=gelman.prior(~mean.novelty, data=select(dat, -trait), scale=sqrt(1+1))
#     ),
#   R=list(V=1,fix=1),
#   G = list(
#     G1 = list(V = 1, nu = 1, alpha.mu = 0, alpha.V = 1000),
#     G2 = list(V = 1, nu = 1, alpha.mu = 0, alpha.V = 1000),
#     G3 = list(V = 1, nu = 1, alpha.mu = 0, alpha.V = 1000),
#     G3 = list(V = 1, nu = 1, alpha.mu = 0, alpha.V = 1000),
#     G4 = list(V = 1, nu = 1, alpha.mu = 0, alpha.V = 1000)
#     )
#   )
# 
# phylmix <-MCMCglmm(
#   fixed = relative.var ~ mean.novelty,
#   family = "ordinal",
#   random = ~ Study.ID + Cross.ID + sp1.name + cross + ES.ID,
#   verbose = FALSE,
#   prior = prior1,
#   ginverse = list(sp1.name = phylo_MCMC),
#   data = select(dat, -trait),
#   nitt = 60000,  # Increase the number of iterations, default is 13000
#   burnin = 5000  # Increase the number of burnin, default is 3000
#   )
# 
# ## Save model ###
# saveRDS(phylmix, file = "../Analysis/novelty.mean.var.obj")

## Load model ###
phylmix <- readRDS("../Analysis/novelty.mean.var.obj")

#+++++++++++++++++++++++++++#
# Fixed effects output 
#+++++++++++++++++++++++++++#
get_fixed.MCMCglmm(summary(phylmix)$solutions) %>%
  dplyr::select("Factors", "Estimates", "95% credible interval", "P", "Description") %>%
  kable("html", digits = 3, caption = "Fixed effects estimates") %>% 
  kable_styling("striped", position = "left")
Fixed effects estimates
Factors Estimates 95% credible interval P Description
(Intercept) 0.23 -1.72 – 1.94 0.678 \(\beta\) = 0.23, CI = -1.72 – 1.94, P = 0.678
mean.noveltyNovel 1.01 0.45 – 1.62 0.000 \(\beta\) = 1.01, CI = 0.45 – 1.62, P = 0
#+++++++++++++++++++++++++++#
# Random effects output 
#+++++++++++++++++++++++++++#
# transformation for varaince
get_random.MCMCglmm(summary(phylmix$VCV/(1+c2))) %>%
  kable("html", digits = 2, caption = "Random effects estimates") %>% 
  kable_styling("striped", position = "left")
Random effects estimates
Random effects Estimates 95% credible interval
Study.ID 1.27 0.14–3.61
Cross.ID 0.23 0–1.12
sp1.name 0.52 0–3.04
cross 18.92 0–138.18
ES.ID 3.21 1.34–5.84
units 0.74 0.74–0.74

The phenotypic novelty (mean.noveltyNovel) influenced positively. This indicates that, compared to non-novel phenotypes, novel phenotypes have greater chances to be more variable than parents’ phenotypes.

Trait mosaicism

F1 hybrids can be seen as “a mosaic of both parental and intermediate morphological characters rather than just intermediate ones” Rieseberg and Ellstrand 1993. That is, F1 hybrid individuals often consist of trats closely resemble one parent, intermediate, and resemble the other parent. Mosaicism indicates tr integration of parents are often collapse in F1 hybrids. Here we investigate the strength of trait mosaicism in male mating traits.

dmismatch calculation

To quantify trait mosaicism in each crossing, we calculated dmismatch following Thompson et al. (2021). dmismatch was calculated as follows:

\(d_{mismatch} = \sqrt{2} * \sqrt{ Z_i^2 + Z_j^2 - \frac{Z_i + Z_j}{\sqrt{2}}^2 }\)
Where \(Z_i\), standardized hybrid trait value in trait \(i\), is
\(Z_i = \frac{hyb_i - spSS_i}{spLL_i - spSS_i}\)

\(Z_i\) is 0-1 if F1 phenotypic mean lies within the range of parents. We note, however, novelty in phenotypic means (transgressive segregation) can result in quite large \(Z_i\): when trait size is large and parental phenotypic divergence is small, novel hybrid phenotype will result in quite large \(Z_i\). This seems occurred in mice (see bellow)

dat <- original.dat %>%
  select(Study.ID, Cross.ID, taxa, Genus, Reciprocal, contains("Mn")) %>%
  # Gather reciprocal hybrid data
  gather(
    key = Hybrid, value = Mn.hybrid, 
    -c(Study.ID, Cross.ID, taxa, Genus, Reciprocal), -contains("Mn.sp")
    ) %>%
  drop_na(Mn.hybrid) %>%
  # Calculate standardized hybrid phenotype mean
  mutate(
    Dominance = ifelse(
      Mn.sp1 > Mn.sp2, 
      (Mn.hybrid - Mn.sp2)/abs(Mn.sp1 - Mn.sp2),
      (Mn.hybrid - Mn.sp1)/abs(Mn.sp1 - Mn.sp2)
    )
  ) %>%
  mutate_at("Cross.ID", as.factor) %>%
  arrange(taxa, Genus, Cross.ID, Hybrid) %>%
  # only get crosses with > 2 traits
  # Reciprocal hybrids are separated
  group_by(Cross.ID, Hybrid, taxa, Genus, Study.ID, Reciprocal) %>%
  filter(n() > 2) %>%
  # Create all combinations of standardized hybrid phenotype mean
  do(data.frame(t(combn(.$Dominance, 2)))) %>%
  # Calculate dominance mismatch
  mutate(
    Mismatch = sqrt(2) * sqrt( X1^2 + X2^2 - ( (X1 + X2) / sqrt(2) )^2 ),
    Mismatch.log = log(Mismatch)
  ) %>%
  left_join(meta) %>%
  mutate_if(is.character, as.factor) %>%
  within(taxa <- ordered(taxa, levels = c("Neuroptera", "Coleoptera", "Diptera", "Lepidoptera", "Orthoptera", "Aves", "Rodentia", "Anura", "Cichliformes"))) %>%
  as.data.frame

Distribution of dmismatch

dat %>% 
  summarise(
    'Trait combination' = length(X1),
    'Species pair' = length(unique(species.pair)),
    'Crossing' = length(unique(Cross.ID))
    ) %>% 
  kable("html", caption = "Dataset summary") %>% 
  kable_styling("striped", position = "left")
Dataset summary
Trait combination Species pair Crossing
15107 20 27
ggplot(data = dat, aes(x = Cross.ID, y = Mismatch)) +
  geom_point(alpha = 0.4, aes(color = Hybrid)) +
  xlab("Cross ID") + ylab("dmismatch") +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  facet_grid(~taxa, scales = "free") +
  ggtitle("All dmismatch values across orders")

ggplot(
  data = dat %>%
    filter(!grepl("musculus", Cross.ID)), 
  aes(x = Cross.ID, y = Mismatch)) +
  xlab("Cross ID") + ylab("dmismatch") +
  geom_point(alpha = 0.4, aes(color = Hybrid)) +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  facet_grid(~taxa, scales = "free") +
  ggtitle("dmismatch across orders excluding Rodentia")

dmismatch is quite large in crossing involving mices (Rodentia), due to large trait value.

General strength of dmismatch

Estimated mean dmismatch across all studies by phylogenetic random model (using MCMCglmm function).

The model included following Random effects estimates:

  • Study.ID: Primary studies

  • sp1.name: Phylogeny of parental species

  • Cross.ID: Parental strain used in the crossing. Discriminate intraspecific populations

  • Hybrid: Crossing direction

  • SE.units: Sampling variance of effect size

#++++++++++++++++++++++++++++++++++#
print("Phylogenetic tree for mcmcglmm")
[1] "Phylogenetic tree for mcmcglmm"
#++++++++++++++++++++++++++++++++++#

# compute branch lengths of tree
phylo_branch <- read.tree(file = "../data/phylo.novelty.tre") %>%
  compute.brlen(method = "Grafen", power = 1)
plot.phylo(phylo_branch, cex = 0.7)

# # saving phylogeneic matrix
# phylo_cor <- vcv(phylo_branch, cor = T)
# 
# # generating inverse phylogenetic matrix for MCMCglmm
# phylo_branch$node.label <- NULL
# phylo_MCMC <- MCMCglmm::inverseA(phylo_branch, nodes = "ALL", scale = TRUE)$Ainv

# phylmix <-MCMCglmm(
#   fixed = Mismatch ~  1,
#   # idh(SE):units | weight by SE of effect size
#   random = ~ Study.ID + sp1.name + Cross.ID + Hybrid,
#   verbose = FALSE,
#   ginverse = list(sp1.name = phylo_MCMC),
#   nitt = 60000,  # Increase the number of iterations, default is 13000
#   burnin = 5000,  # Increase the number of burnin, default is 3000
#   data = dat
# )
# saveRDS(phylmix, file = "../Analysis/mismatch.obj")

phylmix <- readRDS("../Analysis/mismatch.obj")

#+++++++++++++++++++++++++++#
# Fixed effects output 
#+++++++++++++++++++++++++++#
get_fixed.MCMCglmm(summary(phylmix)$solutions) %>%
  dplyr::select("Factors", "Estimates", "95% credible interval", "P", "Description") %>%
  kable("html", digits = 3, caption = "Fixed effects estimates") %>% 
  kable_styling("striped", position = "left")
Fixed effects estimates
Factors Estimates 95% credible interval P Description
(Intercept) 4.41 -3.05 – 10.29 0.166 \(\beta\) = 4.41, CI = -3.05 – 10.29, P = 0.166
#+++++++++++++++++++++++++++#
# Random effects output 
#+++++++++++++++++++++++++++#
# transformation for varaince
get_random.MCMCglmm(summary(phylmix$VCV)) %>%
  kable("html", digits = 2, caption = "Random effects estimates") %>% 
  kable_styling("striped", position = "left")
Random effects estimates
Random effects Estimates 95% credible interval
Study.ID 1.18 0–11.21
sp1.name 8.31 0–70.99
Cross.ID 42.58 13.07–101.37
Hybrid 28.14 0–61.22
units 2801.56 2740.38–2865.59

Even data included quite large dmismatch, overall it did not differ from 0. Yet, the estimate (β = 4.41, CI = -3.05 – 10.29) is still much larger than previously reported mean dmismatch 0.6 Thompson et al. 2019. This is presumably because novelty in phenotypic means, which should increase dmismatch, is much more frequent in our data compared to Thompson et al. 2019.

Factors affecting dmismatch

We asked if any species-level moderators (Genetic divergence between parents, Genet.divergence; Viability of reciprocal cross, Reciprocal; Heterogametic sex, Hetero.sex; Parents’ distribution overlap, Distribution) influence dmismatch values by phylogenetic random model. Random effects were identical as [above] (## General pattern of mismatch dmismatch).

dat3 <- dat %>%
  drop_na(Genet.divergence, Reciprocal, Hetero.sex, Distribution)

# phylmix <-MCMCglmm(
#   fixed = Mismatch ~  Genet.divergence + Reciprocal + Hetero.sex + Distribution,
#   # idh(SE):units | weight by SE of effect size
#   random = ~ Study.ID + sp1.name + Cross.ID + Hybrid,
#   verbose = FALSE,
#   ginverse = list(sp1.name = phylo_MCMC),
#   nitt = 60000,  # Increase the number of iterations, default is 13000
#   burnin = 5000,  # Increase the number of burnin, default is 3000
#   data = dat3
# )
# saveRDS(phylmix, file = "../Analysis/mismatch.reg.obj")

phylmix <- readRDS("../Analysis/mismatch.reg.obj")

#+++++++++++++++++++++++++++#
# Fixed effects output 
#+++++++++++++++++++++++++++#
get_fixed.MCMCglmm(summary(phylmix)$solutions)  %>%
  dplyr::select("Factors", "Estimates", "95% credible interval", "P", "Description") %>%
  kable("html", digits = 3, caption = "Fixed effects estimates") %>% 
  kable_styling("striped", position = "left")
Fixed effects estimates
Factors Estimates 95% credible interval P Description
(Intercept) -1.72 -27.5 – 23.1 0.903 \(\beta\) = -1.72, CI = -27.5 – 23.1, P = 0.903
Genet.divergence -1.38 -11.56 – 8.6 0.788 \(\beta\) = -1.38, CI = -11.56 – 8.6, P = 0.788
ReciprocalViable -8.27 -39.1 – 19.25 0.562 \(\beta\) = -8.27, CI = -39.1 – 19.25, P = 0.562
Hetero.sexMale 11.74 -24.15 – 50.92 0.512 \(\beta\) = 11.74, CI = -24.15 – 50.92, P = 0.512
DistributionAllopatry -2.59 -31.14 – 27.31 0.847 \(\beta\) = -2.59, CI = -31.14 – 27.31, P = 0.847
#+++++++++++++++++++++++++++#
# Random effects output 
#+++++++++++++++++++++++++++#
# transformation for varaince
get_random.MCMCglmm(summary(phylmix$VCV)) %>%
    kable("html", digits = 2, caption = "Random effects estimates") %>% 
    kable_styling("striped", position = "left")
Random effects estimates
Random effects Estimates 95% credible interval
Study.ID 2.54 0–23.35
sp1.name 4.78 0–48.3
Cross.ID 60.43 12.36–204.15
Hybrid 259.92 0–114.81
units 2874.72 2809.1–2941.75

None of species level moderators did not influence dmismatch, as Thompson et al. 2019 showed.

Meta-analysis for phenotypic variation (using lnVR)

Allign parental species according to phenotypic variation

To investigate paternal effect in hybrids using difference in variance between reciprocal cross, it’s better to allign species with larger phenotypic variance (spLLV2) and smaller CV (spSSV2) in each traits. Name of hybrids will be changed according to change in names of parental species (hybridLSV2 & hybridSLV2).

#+++++++++++++++++++++++++++++++++++++++++++++++++#
# sp1 >= sp2 in phenotypic variation
#+++++++++++++++++++++++++++++++++++++++++++++++++#
# extract
sp1sp2.var <- original.dat %>%
  filter(SD.sp1 >= SD.sp2) # filtering according to CV of parentals
# change column name from sp1 or sp2 -> spL or spS
names(sp1sp2.var) <- gsub("1", "L", names(sp1sp2.var))
names(sp1sp2.var) <- gsub("2", "S", names(sp1sp2.var))

#+++++++++++++++++++++++++++++++++++++++++++++++++#
# sp1 < sp2 in phenotypic variation
#+++++++++++++++++++++++++++++++++++++++++++++++++#
# extract
sp2sp1.var <- original.dat %>%
  filter(SD.sp1 < SD.sp2)
# change column name from sp1 or sp2 -> spS or spL
names(sp2sp1.var) <- gsub("1", "S", names(sp2sp1.var))
names(sp2sp1.var) <- gsub("2", "L", names(sp2sp1.var))

#+++++++++++++++++++++++++++++++++++++++++++++++++#
# combine dataset & sort by ES.ID 
#+++++++++++++++++++++++++++++++++++++++++++++++++#
bind_rows(sp1sp2.var, sp2sp1.var) %>%
  arrange(ES.ID) %>%
  write.csv("../data/dat.var.csv", quote=F,row.names = F)

Effect size calculation

We quantified relative phenotypic variability of hybrids and the parent with large variability (spLLV2) to the parent with small variability (spSSV2), by using lnVR. We compared variance itself, and did not controll mean-variance relationship.
Effecct size was calculated by using escalc function in metafor package

# load spLS files
dat <- read.csv("../data/dat.var.csv", head = TRUE)

# Order by taxon
dat$taxa <- ordered(
  dat$taxa,
  levels = c("Neuroptera", "Coleoptera", "Diptera", "Lepidoptera", "Orthoptera", "Aves", "Rodentia", "Anura", "Cichliformes")
  )

var.dif <- foreach(
  cr = c("hybLS", "hybSL", "spL"), 
  .combine = `rbind`
  ) %do% {
    escalc(
      measure = "VR",
      # N of hybrids
      n1i = dat[, paste("N", cr, sep = ".")],
      # N of parentals
      n2i = dat[, "N.spS"],
      # Mean of hybrids
      m1i = dat[, paste("Mn", cr, sep = ".")],
      # Mean of parentals
      m2i = dat[, "Mn.spS"],
      # SD of hybrids]
      sd1i = dat[, paste("SD", cr, sep = ".")],
      # SD of parentals
      sd2i = dat[, "SD.spS"],
      data = dat
      ) %>%
    rename(lnVR.es = yi, lnVR.sv = vi) %>%
    mutate(cross = cr)
    } %>%
  drop_na(lnVR.es) %>%
  arrange(ES.ID) %>%
  left_join(., dat)

write.csv(var.dif, "../data/lnVR.ES.general.csv", row.names = F)

Funnel plots

res <- rma(yi = lnVR.es, vi = lnVR.sv, data = var.dif, method="FE")

## set up 2x2 array for plotting
par(mfrow=c(2,2))
## draw funnel plots
funnel(res, main="Standard Error", xlim = c(-5, 5))
funnel(res, yaxis="vi", main="Sampling Variance", xlim = c(-5, 5))
funnel(res, yaxis="seinv", main="Inverse Standard Error", xlim = c(-5, 5))
funnel(res, yaxis="vinv", main="Inverse Sampling Variance", xlim = c(-5, 5))

Jugding novelty in phenotypic variabilities

# load spLS files
dat <- read.csv("../data/dat.var.csv", head = TRUE)

#+++++++++++++++++++++++++++++++++++++++++++++++++++++++#
# Difference between larger species (spL) and hybrids 
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++#

for (i in c("spL")) { # identify type of hybrids
  for (cr in c("hybLS", "hybSL")) { # identify type of parentals
    assign(
      paste(cr, i, sep = "_"),
        escalc(
          measure = "VR",
          # N of hybrids
          n1i = dat[, paste("N", i, sep = ".")],
          # N of parentals
          n2i = dat[, paste("N", cr, sep = ".")],
          # Mean of hybrids
          m1i = dat[, paste("Mn", i, sep = ".")],
          # Mean of parentals
          m2i = dat[, paste("Mn", cr, sep = ".")],
          # SD of hybrids
          sd1i = dat[, paste("SD", i, sep = ".")],
          # SD of parentals
          sd2i = dat[, paste("SD", cr, sep = ".")],
          data = dat
          ) %>%
          select(ES.ID, yi, vi) %>%
          rename("lnVR.es" = "yi", "lnCVR.sv" = "vi") %>% 
        mutate(
          # direction of transgressve segregation - greater than parent
          direction = "+",
          # SE for logistic distribution, for the weighted binomial regression
          # SE = pi/sqrt(3*(n_e + n_c))
          SE = pi/sqrt(3*(
            dat[, paste("N", i, sep = ".")] + dat[, paste("N", cr, sep = ".")]
          ))
        )
    )
  }
}

#+++++++++++++++++++++++++++++++++++++++++++++++++++++++#
# Difference between hybrids and smaller species (spS)
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++#

for (i in c("hybLS", "hybSL")) { # identify type of hybrids
  for (cr in c("spS")) { # identify type of parentals
    assign(
      paste(i, cr, sep = "_"),
        escalc(
          measure = "VR",
          # N of hybrids
          n1i = dat[, paste("N", i, sep = ".")],
          # N of parentals
          n2i = dat[, paste("N", cr, sep = ".")],
          # Mean of hybrids
          m1i = dat[, paste("Mn", i, sep = ".")],
          # Mean of parentals
          m2i = dat[, paste("Mn", cr, sep = ".")],
          # SD of hybrids
          sd1i = dat[, paste("SD", i, sep = ".")],
          # SD of parentals
          sd2i = dat[, paste("SD", cr, sep = ".")],
          data = dat
          ) %>%
          select(ES.ID, yi, vi) %>%
          rename("lnVR.es" = "yi", "lnCVR.sv" = "vi") %>% 
        mutate(
          # direction of transgressve segregation - smaller than parent
          direction = "-",
          # SE for logistic distribution, for the weighted binomial regression
          # SE = pi/sqrt(3*(n_e + n_c))
          SE = pi/sqrt(3*(
            dat[, paste("N", i, sep = ".")] + dat[, paste("N", cr, sep = ".")]
          ))
        )
    )
  }
}


#+++++++++++++++++++++++++++++++++++++++++++++++++++++++#
# Data output
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++#

bind_rows(
  ## Difference with mother species ###
  bind_rows(hybLS_spL, hybSL_spS) %>%
    mutate(parental = "Mother"),
  ## Difference with father species ###
  bind_rows(hybLS_spS, hybSL_spL) %>%
    mutate(parental = "Father")
  ) %>%
  drop_na(lnVR.es) %>%
  left_join(., dat) %>%
  # Assign novel variability to 1, non-novel variability to 0 for each effect size
  mutate(Novelty = ifelse(lnVR.es < 0, 1, 0)) %>%
  ## Join with metadata ###
  left_join(
    .,
    read.xlsx(
      "../data/original.data.xlsx", sheet = "Species.level.moderators"
      )
    ) %>%
  mutate_at(vars(contains("divergence")), as.numeric) %>%
  mutate_at(vars(contains("divergence")), scale) %>%
  as.data.frame %>%
  select(-trait) %>%
  drop_na(Hetero.sex, trait.type, Genet.divergence) %>%
  # order taxon
  within(
    taxa <- ordered(
      taxa,
      levels = c("Neuroptera", "Coleoptera", "Diptera", "Lepidoptera", "Orthoptera", "Aves", "Rodentia", "Anura", "Cichliformes")
      )
    ) %>%
  mutate_if(is.character, as.factor) %>%
  # Insect or no
  mutate(
    insect = ifelse(taxa %in% c("Aves", "Rodentia", "Anura", "Cichliformes"), "no", "insect"),
  ) %>%
  write.csv("../data/lnVR.ES.Novelty.csv", row.names = F)

Reload data & Prepare phylogenetic tree

# Load effect sizes
var.dif <- read.csv("../data/lnVR.ES.general.csv", head = TRUE)%>%
  # indicate dataset including novel variability
  mutate(data.type = "Alltraits")

# Observations with novel variability
All <- read.csv("../data/lnVR.ES.novelty.csv", head = TRUE) %>%
  filter(lnVR.es < 0) %>%
  distinct(ES.ID)

# Effect sizes with non-novel variability
Nonovel <- read.csv("../data/lnVR.ES.general.csv", head = TRUE) %>%
  filter(!ES.ID %in% unique(All$ES.ID)) %>%
  # indicate dataset without novel variability
  mutate(data.type = "Nonnoveltraits")

# combine dataset with/without novel variability
Novel.Nonnovel <- bind_rows(var.dif, Nonovel) %>%
  mutate(metaunit =  str_c(data.type, cross, sep = "_")) %>%
  # Use observations with both reciprocal crosses
  drop_na(contains("Mn"), contains("SD")) %>%
  # Insect or no
  mutate(
    insect = ifelse(taxa %in% c("Cichliformes", "Anura", "Aves", "Rodentia"), "no", "insect"),
  )

#+++++++++++++++++++++++++++++++#
# Phylogeny 
#+++++++++++++++++++++++++++++++#

# # matching names from open tree taxonomy
# taxa <- tnrs_match_names(
#   names = levels(var.dif$spL.name) %>%
#     str_replace_all("_", " "),
#   context_name = "Animals"
#   )
# 
# # Create tree
# tree <- tol_induced_subtree(ott_ids = taxa$ott_id)
# tree$tip.label %<>%
#   strip_ott_ids # remove OTT IDs from tip labels
# # randomly solve non-binary phylogeny
# set.seed(6)
# bin.tree <- multi2di(tree, random = T)
# 
# # Fix names of tip labels
# bin.tree$tip.label %<>% str_replace_all("Dryophytes", "Hyla")
# # Indicate mismatch between tip labels & dataset species names
# setdiff(levels(as.factor(bin.tree$tip.label)), levels(var.dif$spL.name))
# setdiff(levels(var.dif$spL.name), levels(as.factor(bin.tree$tip.label)))
# 
# write.tree(bin.tree, file= "../data/phylo.lnVR.tre")

# compute branch lengths of tree
phylo_branch <- read.tree(file = "../data/phylo.lnVR.tre") %>%
  compute.brlen(bin.tree, method = "Grafen", power = 1)

# saving phylogeneic matrix
phylo_cor <- vcv(phylo_branch, cor = T)

# Note one of the tips is called "Lates calcarifer (estimated)"
phylo_branch$node.label <- NULL

# Plot tree
plot.phylo(phylo_branch, cex = 0.7)

Dominance in phenotypic variability (coefficient of variation)

We compared midparent-value of phenotypic variability and hybrids’ phenotypic variability by calculating log ratio of phenotypic variability (lnVR) of midparent-value and hybrids to spSSV.

It’s sampling variance was substitute by that of spLLV

We statistically compared those effect sizes through the formal meta-regression by using rma.mv function of R package metafor

All meta-analytic models included following Random effects estimates:

  • Study.ID: Primary studies. Denoted as Study

  • Cross.ID: Parental strain used in the crossing. Discriminate intraspecific populations. Denoted as crossed strain

  • spL.name: Phylogeny of parental species (spLLM). Denoted as species with phylogeny

#+++++++++++++++++++++++++++++++++++++++++++#
# Calculate midparent 
#+++++++++++++++++++++++++++++++++++++++++++#
midparent <- Novel.Nonnovel %>%
   mutate(
     lnVR.midparent.es =
       ifelse(
         cross == "spL",
         # log(Se/Sc)
         log((SD.spL + SD.spS)/2) - log(SD.spS) +  
           # 1/2(Ne-1) - 1/2(Nc-1)
           1/(N.spL + N.spS -2) - 1/(2*N.spS - 2), 
         lnVR.es
         )
     # Divide variance by 4 in spL whereas hybrids are constant
     ) %>%
   mutate_at("cross", as.factor) %>%
   within(levels(cross) <- c("hybLS", "hybSL", "midparent"))


#+++++++++++++++++++++++++++++++++++++++++++++++++++#
# Compare midparent and hybrids by meta-regresson
#+++++++++++++++++++++++++++++++++++++++++++++++++++#

for (tr in c("Alltraits", "Nonnoveltraits")) {
  for (taxon in c("alltaxon", "insect")) {
    
    # Filtering taxon (all taxon or insects)
    if (taxon == "alltaxon") {
      dat <- midparent %>% 
        filter(data.type == tr)
    } else {
      dat <- midparent %>% 
        filter(data.type == tr, insect == taxon)
    }

    #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
    # Estimate meta-analytic mean of midparent of phenotypic variation
    #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
    # midparent.compare <- rma.mv(
    #   yi = lnVR.midparent.es, V = lnVR.sv,
    #   data = dat,
    #   method = "REML",
    #   random = list(~1 | spL.name, ~1 | Study.ID, ~1 | Cross.ID, ~1 | ES.ID),
    #   R = list(spL.name = phylo_cor),
    #   mods = ~ relevel(cross, ref = "midparent")
    #   )
    # ## Save model ###
    # saveRDS(
    #   midparent.compare,
    #   file = paste("../Analysis/lnVR.midparent.compare", tr, taxon, "obj", sep = ".")
    #   )
  
    assign(
      paste("Dominance", tr, taxon, sep = "."),
      readRDS(paste("../Analysis/lnVR.midparent.compare", tr, taxon, "obj", sep = ".")) %>% 
        get_reg() %>%
        # Show dataset name
        within(Dataset <- c(paste(tr, taxon), rep("", length(.$Estimate)-1))) %>%
        # Rename fixed effects
        within('Fixed effects' <- c("", "midparent (intrcpt)", "hybLS", "hybSL")) %>%
        # Difference of each cross from midparent in %
        mutate('Comparison with midparent' = c(
          rep("", 2),
          # Difference hybLS - midparent
          paste(
            round(
            100*(exp(midparent.compare$beta[1]+midparent.compare$beta[2])            -exp(midparent.compare$beta[1])), # hybrid LS
            2),
            "% larger"
            ),
              # beta[1] : midparent
              # beta[2] : hybLS
              # beta[3] : hybSL
          # Difference hybSL - midparent
          paste(
            round(
            100*(exp(midparent.compare$beta[1]+midparent.compare$beta[3])-exp(midparent.compare$beta[1])), # hybrid SL
            2),
            "% larger"
            )
          ))
      )

    #++++++++++++++++++++++++++++++++++++++++++++++#
    # Meta-analysis for midparent to plot band
    #++++++++++++++++++++++++++++++++++++++++++++++#
    # midparent.random <- rma.mv(
    #   yi = lnVR.midparent.es,
    #   V = lnVR.sv,
    #   data = dat %>%
    #     filter(cross == "midparent"),
    #   method = "REML",
    #   random = list(~1 | spL.name, ~1 | Study.ID, ~1 | Cross.ID, ~1 | ES.ID),
    #   R = list(spL.name = phylo_cor)
    #   )
    # ## Save model ###
    # saveRDS(
    #   midparent.random,
    #   file = paste("../Analysis/lnVR.midparent", tr, taxon, "obj", sep = ".")
    #   )
    
  }
}

bind_rows(
  Dominance.Alltraits.alltaxon, Dominance.Nonnoveltraits.alltaxon,
  Dominance.Alltraits.insect, Dominance.Nonnoveltraits.insect
  ) %>%
  kable("html", digits = 3, caption = "Meta-analyses results of full dataset and data subsets") %>%
  kable_styling("striped", position = "left") %>%
  scroll_box(width = "100%", height = "500px")
Meta-analyses results of full dataset and data subsets
Dataset Fixed effects Estimate LowerCI UpperCI P I2[total] %I2[species with phylogeny] %I2[study] %I2[crossed strain] %I2[residual] significance Comparison with midparent
Alltraits alltaxon 87.9% 1.2% 14.2% 0% 72.6%
midparent (intrcpt) 0.542 0.340 0.743 0.000
hybLS -0.049 -0.116 0.019 0.157 -21.11 % larger
hybSL -0.083 -0.150 -0.016 0.015
-24.94 % larger
Nonnoveltraits alltaxon 82.1% 0% 23.9% 0% 58.2%
midparent (intrcpt) 0.756 0.536 0.976 0.000
hybLS -0.142 -0.232 -0.052 0.002
-21.11 % larger
hybSL -0.140 -0.228 -0.051 0.002
-24.94 % larger
Alltraits insect 87.7% 0% 10% 0% 77.7%
midparent (intrcpt) 0.478 0.300 0.656 0.000
hybLS -0.063 -0.133 0.006 0.074 -21.11 % larger
hybSL -0.107 -0.176 -0.038 0.002
-24.94 % larger
Nonnoveltraits insect 82.4% 0% 24.2% 0% 58.2%
midparent (intrcpt) 0.722 0.485 0.960 0.000
hybLS -0.167 -0.260 -0.074 0.000
-21.11 % larger
hybSL -0.179 -0.270 -0.088 0.000
-24.94 % larger

Crossing direction effect in phenotypic variability (coefficient of variation)

We statistically compared lnVR from spSSM to the other crosses through the formal meta-regression by using rma.mv function of R package metafor.
Here we asked if lnVR of hybSLV was smaller/larger than that of hybLSV. Smaller lnVR of hybSLV indicates maternal inheritance in phenotypic variability

for (tr in c("Alltraits", "Nonnoveltraits")) {

  if (taxon == "alltaxon") {
    dat <- Novel.Nonnovel %>% 
      filter(data.type == tr)
  } else {
    dat <- Novel.Nonnovel %>% 
      filter(data.type == tr, insect == taxon)
  }
    
  for (taxon in c("alltaxon", "insect")) {
  #++++++++++++++++++++++++++++++++++++++++++++++#
  # phylogenetic random regresson (ANOVA)
  #++++++++++++++++++++++++++++++++++++++++++++++#
  # phyl.random.hybLS <- rma.mv(
  #   yi = lnVR.es, V = lnVR.sv,
  #   data = dat, method = "REML",
  #   random = list(~1 | spL.name, ~1 | Study.ID, ~1 | Cross.ID, ~1 | ES.ID),
  #   R = list(spL.name = phylo_cor),
  #   mods = ~ cross
  #   )
  # # Save model ###
  # saveRDS(
  #   phyl.random.hybLS,
  #   file = paste("../Analysis/lnVR.compare.from.hybLS", tr, taxon, "obj", sep = ".")
  #   )
    
    phyl.random.hybLS <- readRDS(
      paste("../Analysis/lnVR.compare.from.hybLS", tr, taxon, "obj", sep = ".")
      )

    assign(
      paste("Reciprocal", tr, taxon, sep = "."),
      phyl.random.hybLS %>% 
        get_reg() %>%
        # Show dataset name
        within(Dataset <- c(paste(tr, taxon), rep("", length(.$Estimate)-1))) %>%
        # Rename fixed effects
        within('Fixed effects' <- c("", "hybLS (intrcpt)", "hybSL", "spLL")) %>%
        # Difference of each cross from midparent in %
        mutate('Comparison with hybridLS' = c(
          rep("", 2),
          paste(
            round(
              (exp(phyl.random.hybLS$beta[1]+phyl.random.hybLS$beta[2]) -
                 exp(phyl.random.hybLS$beta[1])
               )*100,
              2),
            "% larger"
            ), 
          ""
          )
        )
      )
  }
}

bind_rows(
  Reciprocal.Alltraits.alltaxon, Reciprocal.Nonnoveltraits.alltaxon,
  Reciprocal.Alltraits.insect, Reciprocal.Nonnoveltraits.insect
  ) %>%
  kable("html", digits = 3, caption = "Meta-analyses results of full dataset and data subsets") %>% 
  kable_styling("striped", position = "left") %>%
  scroll_box(width = "100%", height = "500px")
Meta-analyses results of full dataset and data subsets
Dataset Fixed effects Estimate LowerCI UpperCI P I2[total] %I2[species with phylogeny] %I2[study] %I2[crossed strain] %I2[residual] significance Comparison with hybridLS
Alltraits alltaxon 89.6% 0% 14.2% 0% 75.3%
hybLS (intrcpt) 0.498 0.301 0.696 0.000
hybSL -0.032 -0.104 0.039 0.378 -5.21 % larger
spLL 0.280 0.212 0.347 0.000
Nonnoveltraits alltaxon 85.8% 0% 23.4% 0% 62.4%
hybLS (intrcpt) 0.641 0.392 0.890 0.000
hybSL 0.007 -0.088 0.101 0.893 1.24 % larger
spLL 0.416 0.326 0.506 0.000
Alltraits insect 89.4% 0% 9.6% 0% 79.8%
hybLS (intrcpt) 0.425 0.233 0.618 0.000
hybSL -0.042 -0.116 0.032 0.261 -6.35 % larger
spLL 0.293 0.223 0.363 0.000
Nonnoveltraits insect 86.1% 0% 23.6% 0% 62.5%
hybLS (intrcpt) 0.582 0.312 0.852 0.000
hybSL -0.009 -0.107 0.089 0.857 -1.6 % larger
spLL 0.438 0.345 0.531 0.000

Session information

sessionInfo()  # show R version etc
R version 3.6.3 (2020-02-29)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 19041)

Matrix products: default

locale:
[1] LC_COLLATE=Japanese_Japan.932  LC_CTYPE=Japanese_Japan.932   
[3] LC_MONETARY=Japanese_Japan.932 LC_NUMERIC=C                  
[5] LC_TIME=Japanese_Japan.932    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] ggimage_0.2.8      patchwork_1.1.1    ggtree_2.1.1       ggbeeswarm_0.6.0  
 [5] ggiraphExtra_0.3.0 svglite_1.2.3.2    pander_0.6.3       kableExtra_1.3.1  
 [9] knitr_1.30         phytools_0.7-70    maps_3.3.0         rotl_3.0.11       
[13] orchaRd_0.0.0.9000 MCMCglmm_2.30      ape_5.4-1          coda_0.19-4       
[17] metafor_2.4-0      Matrix_1.2-18      foreach_1.5.1      magrittr_2.0.1    
[21] forcats_0.5.0      stringr_1.4.0      dplyr_1.0.2        purrr_0.3.4       
[25] readr_1.4.0        tidyr_1.1.2        tibble_3.0.4       ggplot2_3.3.3     
[29] tidyverse_1.3.0    openxlsx_4.2.3    

loaded via a namespace (and not attached):
  [1] readxl_1.3.1            uuid_0.1-4              backports_1.2.1        
  [4] fastmatch_1.1-0         systemfonts_0.3.2       plyr_1.8.6             
  [7] igraph_1.2.6            lazyeval_0.2.2          splines_3.6.3          
 [10] mycor_0.1.1             rncl_0.8.4              digest_0.6.27          
 [13] htmltools_0.5.0         magick_2.5.2            fansi_0.4.1            
 [16] modelr_0.1.8            prettyunits_1.1.1       colorspace_2.0-0       
 [19] rvest_0.3.6             haven_2.3.1             xfun_0.20              
 [22] crayon_1.3.4            jsonlite_1.7.2          phangorn_2.5.5         
 [25] iterators_1.0.13        glue_1.4.2              gtable_0.3.0           
 [28] ppcor_1.1               webshot_0.5.2           sjmisc_2.8.6           
 [31] rentrez_1.2.3           scales_1.1.1            DBI_1.1.0              
 [34] Rcpp_1.0.5              plotrix_3.7-8           viridisLite_0.3.0      
 [37] progress_1.2.2          tmvnsim_1.0-2           gridGraphics_0.5-1     
 [40] tidytree_0.3.3          htmlwidgets_1.5.3       httr_1.4.2             
 [43] RColorBrewer_1.1-2      ellipsis_0.3.1          farver_2.0.3           
 [46] pkgconfig_2.0.3         XML_3.99-0.3            dbplyr_2.0.0           
 [49] labeling_0.4.2          ggplotify_0.0.5         tidyselect_1.1.0       
 [52] rlang_0.4.10            reshape2_1.4.4          munsell_0.5.0          
 [55] cellranger_1.1.0        tools_3.6.3             cli_2.2.0              
 [58] generics_0.1.0          pacman_0.5.1            sjlabelled_1.1.7       
 [61] broom_0.7.3             evaluate_0.14           yaml_2.2.1             
 [64] fs_1.5.0                zip_2.1.1               nlme_3.1-151           
 [67] ggiraph_0.7.8           xml2_1.3.2              compiler_3.6.3         
 [70] rstudioapi_0.13         beeswarm_0.2.3          curl_4.3               
 [73] reprex_0.3.0            treeio_1.11.2           clusterGeneration_1.3.7
 [76] stringi_1.5.3           highr_0.8               gdtools_0.2.3          
 [79] cubature_2.0.4.1        lattice_0.20-38         tensorA_0.36.2         
 [82] vctrs_0.3.6             pillar_1.4.7            lifecycle_0.2.0        
 [85] BiocManager_1.30.10     combinat_0.0-8          insight_0.11.1         
 [88] corpcor_1.6.9           R6_2.5.0                vipor_0.4.5            
 [91] codetools_0.2-16        MASS_7.3-53             gtools_3.8.2           
 [94] assertthat_0.2.1        withr_2.3.0             mnormt_2.0.2           
 [97] mgcv_1.8-31             expm_0.999-5            parallel_3.6.3         
[100] hms_0.5.3               quadprog_1.5-8          grid_3.6.3             
[103] rmarkdown_2.6           rvcheck_0.1.8           numDeriv_2016.8-1.1    
[106] scatterplot3d_0.3-41    lubridate_1.7.9.2      

References

Alibert, P., and J.-C. Auffray. 2003. Genomic coadaptation, outbreeding depression and developmental instability. Pp. 116–134 in M. Polak, ed. Developmental instability: Causes and consequences. Oxford University Press, New York.
Bridle, J. R., C. I. Saldamando, W. Koning, and R. K. Butlin. 2006. Assortative preferences and discrimination by females against hybrid male song in the grasshoppers Chorthippus brunneus and <i>Chorthippus jacobsi</i> (Orthoptera: Acrididae). Journal of Evolutionary Biology 19:1248–1256.
Cockett, N. E., S. P. Jackson, T. L. Shay, F. Farnir, S. Berghmans, G. D. Snowder, D. M. Nielsen, and M. Georges. 1996. Polar overdominance at the ovine callipyge locus. Science 273:236–238.
Doherty, J. A., and H. C. Gerhardt. 1984. Acoustic communication in hybrid treefrogs: sound production by males and selective phonotaxis by females. Journal of Comparative Physiology A 154:319–330.
Edmands, S. 1999. Heterosis and outbreeding depression in interpopulation crosses spanning a wide range of divergence. Evolution 53:1757.
Gottsberger, B., and F. Mayer. 2019. Dominance effects strengthen premating hybridization barriers between sympatric species of grasshoppers (Acrididae, Orthoptera). Journal of Evolutionary Biology 921–930.
Haldane, J. B. S. 1922. Sex ratio and unisexual sterility in hybrid animals. Journal of Genetics 12:101–109.
Hochkirch, A., and I. Lemke. 2011. Asymmetric mate choice, hybridization, and hybrid fitness in two sympatric grasshopper species. Behavioral Ecology and Sociobiology 65:1637–1645.
Hoffmann, A. A., J. Merilä, and T. N. Kristensen. 2016. Heritability and evolvability of fitness and nonfitness traits: Lessons from livestock. Evolution; international journal of organic evolution 70:1770–1779.
Isoherranen, E., J. Aspi, and A. Hoikkala. 1999. Inheritance of species differences in female receptivity and song requirement between Drosophila virilis and D. montana. Hereditas 131:203–209.
Lamkey, K. R., and J. W. Edwards. 1999. Quantitative genetics of heterosis. Pp. 31–48 in J. G. Coors and S. Pandey, eds. The genetics and exploitation of heterosis in crops. CIMMYT, Mexico City.
Lerner, I. M. 1954. Genetic homeostasis. Oliver; Boyd, Edinburgh, Scotland.
Nakagawa, S., R. Poulin, K. Mengersen, K. Reinhold, L. Engqvist, M. Lagisz, and A. M. Senior. 2015. Meta-analysis of variation: Ecological and evolutionary applications and beyond. Methods in Ecology and Evolution 6:143–152.
Rieseberg, L. H., M. A. Archer, and R. K. Wayne. 1999. Transgressive segregation, adaptation and speciation. Heredity 83:363–372.
Ritchie, M. G. 2000. The inheritance of female preference functions in a mate recognition system. Proceedings of the Royal Society B: Biological Sciences 267:327–332.
Schilthuizen, M., M. C. W. G. Giesbers, and L. W. Beukeboom. 2011. Haldane’s rule in the 21st century. Heredity 107:95–102.
Shaw, K. L. 2000. Interspecific genetics of mate recognition: Inheritance of female acoustic preference in Hawaiian crickets. Evolution 54:1303–1312. Department of Organismic; Evolutionary Biology, Harvard University, Cambridge, MA 02138, United States.
Thompson, K. A., M. Urquhart-Cronish, K. D. Whitney, L. H. Rieseberg, and D. Schluter. 2021. Patterns, Predictors, and Consequences of Dominance in Hybrids. The American Naturalist 197:E000–E000.
LS0tDQp0aXRsZTogIk5vbi1hZGRpdGl2ZSBnZW5ldGljIGVmZmVjdHMgaW5kdWNlIG5vdmVsIHBoZW5vdHlwaWMgZGlzdHJpYnV0aW9ucyBpbiBtYWxlIG1hdGluZyB0cmFpdHMgb2YgRjEgaHlicmlkcyINCmF1dGhvcjogIktlaXN1a2UgQXRzdW1pLCBNYWxnb3J6YXRhIExhZ2lzeiAmIFNoaW5pY2hpIE5ha2FnYXdhIg0KZGF0ZTogJ2ByIGZvcm1hdChTeXMudGltZSgpLCAiJXkvJW0vJWQgJUg6JU0iKWAnDQpiaWJsaW9ncmFwaHk6IHBoZW5vX2Rpc3RfaHliLmJpYiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KY3NsOiBldm9sdXRpb24uY3NsIA0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgICB0aGVtZTogdW5pdGVkICMg4oCcZGVmYXVsdOKAnSwg4oCcY2VydWxlYW7igJ0sIOKAnGpvdXJuYWzigJ0sIOKAnGZsYXRseeKAnSwg4oCcZGFya2x54oCdLCDigJxyZWFkYWJsZeKAnSwg4oCcc3BhY2VsYWLigJ0sIOKAnHVuaXRlZOKAnSwg4oCcY29zbW/igJ0sIOKAnGx1bWVu4oCdLCDigJxwYXBlcuKAnSwg4oCcc2FuZHN0b25l4oCdLCDigJxzaW1wbGV44oCdLCDigJx5ZXRp4oCdDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZmxvYXQ6IHllcw0Kc3VidGl0bGU6IFN1cHBsZW1lbnRhcnkgSW5mb3JtYXRpb24NCg0KLS0tDQoNCjxkaXYgc3R5bGU9Im1hcmdpbi1ib3R0b206MTIwcHg7Ij4NCjwvZGl2Pg0KDQojIyBTZXR1cA0KDQojIyBMb2FkIHBhY2thZ2VzDQoNCmBgYHtyfQ0KDQpybShsaXN0PWxzKCkpICAjIHJlc2V0IHdvcmtzcGFjZQ0Kb3B0aW9ucyhzY2lwZW49MTAwKSAgIyBkbyBub3Qgc2hvdyBudW1iZXJzIHVzaW5nIGV4cG9uZW50aWFsDQoNCiMgaW5zdGFsbCAmIGxvYWQgcGFja2FnZXMNCnBhY21hbjo6cF9sb2FkKA0KICBvcGVueGxzeCAgICMgb3BlbiBleGNlbA0KICAsIHRpZHl2ZXJzZQ0KICAsIG1hZ3JpdHRyICAgIyBleHRlbmRlZCBwaXBlDQogICwgZm9yZWFjaCAgICAjIFBhcmFsbGVsIHByb2Nlc3NpbmcNCiAgLCBtZXRhZm9yICAgICMgbWV0YS1hbmFseXNpcw0KICAsIE1DTUNnbG1tICAgIyBjb21wYXJhdGl2ZSBhbmFseXNpcw0KICAsIG9yY2hhUmQgICAgIyBPcmNoYXJkIHBsb3QgLSBtZXRhLWFuYWx5c2lzDQogICwgcm90bCAgICAgICAjIG9wZW4gdHJlZSBvZiBsaWZlDQogICwgYXBlICAgICAgICAjIFBoeWxvZ2VueQ0KICAsIHBoeXRvb2xzICAgIyBQaHlsb2dlbnkNCiAgLCBrbml0ciAgDQogICwga2FibGVFeHRyYSAjIG5pY2UgdGFibGVzDQogICwgcGFuZGVyICAgICAjIG5pY2UgdGFibGVzDQogICwgc3ZnbGl0ZSAgICAjIEV4cG9ydCBTVkcgcGxvdHMNCiAgLCBnZ2lyYXBoRXh0cmEgIyBHZW9tIHByZWRpY3QNCiAgLCBnZ2JlZXN3YXJtICMgT3JjaGFyZCBwbG90DQogICwgZ2d0cmVlDQogICwgcGF0Y2h3b3JrICAgIyBjb21iaW5lIG11bHRpcGxlIHBsb3RzDQogICMgLCBSLnJzcA0KKQ0KDQojIFJtYXJrZG93biBzZXR0aW5ncw0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KA0KICBwcm9tcHQgID0gRkFMU0UsICAjIERvIG5vdCBhZGQgPiBvciArIGluIGlubGluZS1jb2RlDQogIG1lc3NhZ2UgPSBGQUxTRSwgDQogIGNvbW1lbnQgPSAiIiwgDQogIHdhcm5pbmcgPSBGQUxTRSwgICMgTXV0ZSB3YXJuaW5ncw0KICB0aWR5ICAgID0gVFJVRQ0KICApIA0Kb3B0aW9ucyhrbml0ci5rYWJsZS5OQSA9ICcnKSAjIEhpZGUgTkFzIGluIGthYmxlIHRhYmxlDQoNCmBgYA0KDQoNCiMjIEN1c3RvbSBmdW5jdGlvbg0KV2UgaGF2ZSBjdXN0b20gZnVuY3Rpb25zIG5hbWVkIDogYGdldF9wcmVkKClgLCBgZ2V0X3JlZygpYCwgYGdldF9maXhlZC5NQ01DZ2xtbSgpYCBhbmQgIGBnZXRfcmFuZG9tLk1DTUNnbG1tKClgLCBhbGwgb2Ygd2hpY2ggYXJlIHVzZWQgbGF0ZXIgKHNlZSBiZWxvdyBmb3IgdGhlaXIgZnVuY3Rpb25hbGl0eSkgYW5kIHRoZSBjb2RlIGFyZSBpbmNsdWRlZCBoZXJlLiANCg0KYGBge3J9DQoNCiMnIFRpdGxlOiBnZXRfcHJlZA0KIycgZnVuY3Rpb24gdG8gZ2V0IHByZWRpY3Rpb24gaW50ZXJ2YWxzIChjcmVkaWJsaXR5IGludGVydmFscykgZnJvbSBybWEgb2JqZWN0cyAobWV0YWZvcikNCiMnDQojJyBAcGFyYW0gbW9kZWw6IHJtYS5tdiBvYmplY3QgDQojJyBAcGFyYW0gbW9kOiB0aGUgbmFtZSBvZiBhIG1vZGVyYXRvciANCmdldF9wcmVkIDwtIGZ1bmN0aW9uKG1vZGVsLCBtb2QgPSAiICIpIHsNCiAgSTIgPC0gaTJfbWwobW9kZWwpICU+JQ0KICAgIGFzLmRhdGEuZnJhbWUoKSAlPiUNCiAgICByb3duYW1lc190b19jb2x1bW4oIlBhcnRpdGlvbiIpICU+JQ0KICAgIHJlbmFtZSgiSTIiID0gIi4iKSAlPiUNCiAgICBtdXRhdGUocGVyY2VudGFnZSA9IHN0cl9jKHJvdW5kKEkyKjEwMCwxKSwiJSIsIHNlcCA9ICIiKSkgJT4lDQogICAgY29sdW1uX3RvX3Jvd25hbWVzKCJQYXJ0aXRpb24iKQ0KDQogIG5hbWUgPC0gYXMuZmFjdG9yKHN0cl9yZXBsYWNlKHJvdy5uYW1lcyhtb2RlbCRiZXRhKSwgbW9kLCAiIikpDQogIGxlbiA8LSBsZW5ndGgobmFtZSkNCiAgDQogIGlmIChsZW4gIT0gMSkgew0KICAgICAgbmV3ZGF0YSA8LSBtYXRyaXgoTkEsIG5jb2wgPSBsZW4sIG5yb3cgPSBsZW4pDQogICAgICBmb3IgKGkgaW4gMTpsZW4pIHsNCiAgICAgICAgICAjIGdldHRpbmcgdGhlIHBvc2l0aW9uIG9mIHVuaXF1ZSBjYXNlIGZyb20gWCAoZGVzaWduIG1hdHJpeCkNCiAgICAgICAgICBwb3MgPC0gd2hpY2gobW9kZWwkWFssIGldID09IDEpW1sxXV0NCiAgICAgICAgICBuZXdkYXRhWywgaV0gPC0gbW9kZWwkWFtwb3MsIF0NCiAgICAgIH0NCiAgICAgIHByZWQgPC0gcHJlZGljdC5ybWEobW9kZWwsIG5ld21vZHMgPSBuZXdkYXRhKQ0KICAgIH0gZWxzZSB7DQogICAgICAgIHByZWQgPC0gcHJlZGljdC5ybWEobW9kZWwpDQogICAgfQ0KDQogICAgdGFibGUgPC0gdGliYmxlKA0KICAgICAgJ0RhdGFzZXQnID0gIiIsDQogICAgICAnRml4ZWQgZWZmZWN0cycgPSBuYW1lLCANCiAgICAgICdFc3RpbWF0ZScgPSBtb2RlbCRiZXRhLCAjIHJlZ3Jlc3Npb246IGVzdGltYXRlDQogICAgICAnTG93ZXJDSScgPSBtb2RlbCRjaS5sYiwgIyByZWdyZXNzaW9uOiA5NWNpLCANCiAgICAgICdVcHBlckNJJyAgPSBtb2RlbCRjaS51YiwgIyByZWdyZXNzaW9uOiA5NWNpDQogICAgICAnbG93ZXJQUicgPSBwcmVkJGNyLmxiLCAgIyBsb3dlciBwcmVkaWN0aW9uIHJhbmdlDQogICAgICAndXBwZXJQUicgPSBwcmVkJGNyLnViLCAjIGxvd2VyIHByZWRpY3Rpb24gcmFuZ2UNCiAgICAgICdQJyAgICAgICAgPSBtb2RlbCRwdmFsLA0KICAgICMgJ1Zbc3BlY2llcyB3aXRoIHBoeWxvZ2VueV0nID0NCiAgICAjICAgYyhtb2RlbCRzaWdtYTJbMV0sIHJlcCgiIiwgbGVuZ3RoKG1vZGVsJGJldGEpKSksDQogICAgIyAnVltzdHVkeV0nID0NCiAgICAjICAgYyhtb2RlbCRzaWdtYTJbMl0sIHJlcCgiIiwgbGVuZ3RoKG1vZGVsJGJldGEpKSksDQogICAgIyAnVltjcm9zc2VkIHN0cmFpbl0nID0NCiAgICAjICAgYyhtb2RlbCRzaWdtYTJbM10sIHJlcCgiIiwgbGVuZ3RoKG1vZGVsJGJldGEpKSksDQogICAgIyAnVltyZXNpZHVhbF0nID0gDQogICAgIyAgIGMobW9kZWwkc2lnbWEyWzRdLCByZXAoIiIsIGxlbmd0aChtb2RlbCRiZXRhKSkpLA0KICAgICdJMlt0b3RhbF0nID0gDQogICAgICBjKEkyWyJJMl90b3RhbCIsInBlcmNlbnRhZ2UiXSwgcmVwKCIiLCBsZW5ndGgobW9kZWwkYmV0YSktMSkpLA0KICAgICclSTJbc3BlY2llcyB3aXRoIHBoeWxvZ2VueV0nID0gDQogICAgICBjKEkyWyJJMl9zcEwubmFtZSIsInBlcmNlbnRhZ2UiXSwgcmVwKCIiLCBsZW5ndGgobW9kZWwkYmV0YSktMSkpLA0KICAgICclSTJbc3R1ZHldJyA9DQogICAgICBjKEkyWyJJMl9TdHVkeS5JRCIsInBlcmNlbnRhZ2UiXSwgcmVwKCIiLCBsZW5ndGgobW9kZWwkYmV0YSktMSkpLA0KICAgICclSTJbY3Jvc3NlZCBzdHJhaW5dJyA9DQogICAgICBjKEkyWyJJMl9Dcm9zcy5JRCIsInBlcmNlbnRhZ2UiXSwgcmVwKCIiLCBsZW5ndGgobW9kZWwkYmV0YSktMSkpLA0KICAgICclSTJbcmVzaWR1YWxdJyA9IA0KICAgICAgYyhJMlsiSTJfRVMuSUQiLCJwZXJjZW50YWdlIl0sIHJlcCgiIiwgbGVuZ3RoKG1vZGVsJGJldGEpLTEpKSwNCiAgICApICAlPiUNCiAgICBhcy5kYXRhLmZyYW1lKCkgJT4lDQogICAgbXV0YXRlX2F0KHZhcnMoJ0VzdGltYXRlJzonUCcpLCBhcy5udW1lcmljKSAlPiUNCiAgICBtdXRhdGUoc2lnbmlmaWNhbmNlID0gaWZlbHNlKFAgPCAwLjA1LCAiKiIsICIiKSkNCn0NCg0KDQoNCiMnIFRpdGxlOiBnZXRfcmVnDQojJyBmdW5jdGlvbiB0byBnZXQgc3VtbWFyeSBzdGF0cyBmcm9tIHJtYSBvYmplY3RzIChtZXRhZm9yKQ0KIycgQHBhcmFtIG1vZGVsOiBybWEubXYgb2JqZWN0IA0KIycgQHBhcmFtIG1vZDogdGhlIG5hbWUgb2YgYSBtb2RlcmF0b3IgDQpnZXRfcmVnIDwtIGZ1bmN0aW9uKG1vZGVsLCBtb2QgPSAiICIpIHsNCiAgDQogIEkyIDwtIGkyX21sKG1vZGVsKSAlPiUNCiAgICBhcy5kYXRhLmZyYW1lKCkgJT4lDQogICAgcm93bmFtZXNfdG9fY29sdW1uKCJQYXJ0aXRpb24iKSAlPiUNCiAgICByZW5hbWUoIkkyIiA9ICIuIikgJT4lDQogICAgbXV0YXRlKHBlcmNlbnRhZ2UgPSBzdHJfYyhyb3VuZChJMioxMDAsMSksIiUiLCBzZXAgPSAiIikpICU+JQ0KICAgIGNvbHVtbl90b19yb3duYW1lcygiUGFydGl0aW9uIikNCiAgDQogIHRhYmxlIDwtIHRpYmJsZSgNCiAgICAnRGF0YXNldCcgPSAiIiwNCiAgICAnRml4ZWQgZWZmZWN0cycgPSBjKCIiLCByb3cubmFtZXMobW9kZWwkYmV0YSkpLA0KICAgICdFc3RpbWF0ZScgPSBjKCIiLCBtb2RlbCRiZXRhKSwgIyByZWdyZXNzaW9uOiBlc3RpbWF0ZQ0KICAgICdMb3dlckNJJyA9IGMoIiIsIG1vZGVsJGNpLmxiKSwgIyByZWdyZXNzaW9uOiA5NWNpLCANCiAgICAnVXBwZXJDSScgID0gYygiIiwgbW9kZWwkY2kudWIpLCAjIHJlZ3Jlc3Npb246IDk1Y2kNCiAgICAnUCcgICAgICAgID0gYygiIiwgbW9kZWwkcHZhbCksDQogICAgIyAnVltzcGVjaWVzIHdpdGggcGh5bG9nZW55XScgPQ0KICAgICMgICBjKG1vZGVsJHNpZ21hMlsxXSwgcmVwKCIiLCBsZW5ndGgobW9kZWwkYmV0YSkpKSwNCiAgICAjICdWW3N0dWR5XScgPQ0KICAgICMgICBjKG1vZGVsJHNpZ21hMlsyXSwgcmVwKCIiLCBsZW5ndGgobW9kZWwkYmV0YSkpKSwNCiAgICAjICdWW2Nyb3NzZWQgc3RyYWluXScgPQ0KICAgICMgICBjKG1vZGVsJHNpZ21hMlszXSwgcmVwKCIiLCBsZW5ndGgobW9kZWwkYmV0YSkpKSwNCiAgICAjICdWW3Jlc2lkdWFsXScgPSANCiAgICAjICAgYyhtb2RlbCRzaWdtYTJbNF0sIHJlcCgiIiwgbGVuZ3RoKG1vZGVsJGJldGEpKSksDQogICAgJ0kyW3RvdGFsXScgPSANCiAgICAgIGMoSTJbIkkyX3RvdGFsIiwicGVyY2VudGFnZSJdLCByZXAoIiIsIGxlbmd0aChtb2RlbCRiZXRhKSkpLA0KICAgICclSTJbc3BlY2llcyB3aXRoIHBoeWxvZ2VueV0nID0gDQogICAgICBjKEkyWyJJMl9zcEwubmFtZSIsInBlcmNlbnRhZ2UiXSwgcmVwKCIiLCBsZW5ndGgobW9kZWwkYmV0YSkpKSwNCiAgICAnJUkyW3N0dWR5XScgPQ0KICAgICAgYyhJMlsiSTJfU3R1ZHkuSUQiLCJwZXJjZW50YWdlIl0sIHJlcCgiIiwgbGVuZ3RoKG1vZGVsJGJldGEpKSksDQogICAgJyVJMltjcm9zc2VkIHN0cmFpbl0nID0NCiAgICAgIGMoSTJbIkkyX0Nyb3NzLklEIiwicGVyY2VudGFnZSJdLCByZXAoIiIsIGxlbmd0aChtb2RlbCRiZXRhKSkpLA0KICAgICclSTJbcmVzaWR1YWxdJyA9IA0KICAgICAgYyhJMlsiSTJfRVMuSUQiLCJwZXJjZW50YWdlIl0sIHJlcCgiIiwgbGVuZ3RoKG1vZGVsJGJldGEpKSksDQogICAgKSAgJT4lDQogICAgYXMuZGF0YS5mcmFtZSgpICU+JQ0KICAgIG11dGF0ZV9hdCh2YXJzKCdFc3RpbWF0ZSc6J1AnKSwgYXMubnVtZXJpYykgJT4lDQogICAgbXV0YXRlKHNpZ25pZmljYW5jZSA9IGlmZWxzZShQIDwgMC4wNSwgIioiLCAiIikpDQp9DQoNCg0KIycgVGl0bGU6IGdldF9yYW5kb20uTUNNQ2dsbW0NCiMnIA0KIycgQHBhcmFtIHg6IFZDViBvZiBNQ01DZ2xtbSBwcm9kdWN0cyAoaS5lLiBzdW1tYXJ5KCdNQ01DZ2xtbSBvYmplY3QnJFZDVikpLCB3aGljaCB3YXMgdHJhbnNmb3JtZWQgaWYgYXBwcmVjYWJsZS4gDQpnZXRfcmFuZG9tLk1DTUNnbG1tIDwtIGZ1bmN0aW9uKHgpIHsNCiAgDQogIGJpbmRfY29scygNCiAgICB4JHN0YXRpc3RpY3MgJT4lDQogICAgYXMuZGF0YS5mcmFtZSwNCiAgICB4JHF1YW50aWxlcyAlPiUNCiAgICBhcy5kYXRhLmZyYW1lDQogICAgKSAgJT4lIA0KICAgIHJvd25hbWVzX3RvX2NvbHVtbigiUmFuZG9tIGVmZmVjdHMiKSAgJT4lIA0KICAgIHJlbmFtZSgiRXN0aW1hdGVzIiA9ICJNZWFuIikgJT4lDQogICAgYXMuZGF0YS5mcmFtZSAlPiUNCiAgICBtdXRhdGUoDQogICAgICAnOTUlIGNyZWRpYmxlIGludGVydmFsJyA9IHN0cl9jKA0KICAgICAgICByb3VuZCguWywiMi41JSJdLDIpLCByb3VuZCguWywiOTcuNSUiXSwyKSwNCiAgICAgICAgc2VwID0gIi0tIiAjIGVuLWRhc2gNCiAgICAgICAgKQ0KICAgICAgKSAlPiUNCiAgICBkcGx5cjo6c2VsZWN0KCJSYW5kb20gZWZmZWN0cyIsICJFc3RpbWF0ZXMiLCAiOTUlIGNyZWRpYmxlIGludGVydmFsIikgDQogIA0KfQ0KDQojJyBUaXRsZTogZ2V0X2ZpeGVkLk1DTUNnbG1tDQojJyANCiMnIEBwYXJhbSB4OiBTb2x1dGlvbiBvZiBNQ01DZ2xtbSBwcm9kdWN0cyAoaS5lLiBzdW1tYXJ5KCdNQ01DZ2xtbSBvYmplY3QnJHNvbHV0aW9ucykpLCB3aGljaCB3YXMgdHJhbnNmb3JtZWQgaWYgYXBwcmVjYWJsZS4gDQpnZXRfZml4ZWQuTUNNQ2dsbW0gPC0gZnVuY3Rpb24oeCkgew0KICANCiAgeCAlPiUNCiAgICBhcy5kYXRhLmZyYW1lKCkgJT4lDQogICAgcm93bmFtZXNfdG9fY29sdW1uKHZhciA9ICJGYWN0b3JzIikgJT4lDQogICAgbXV0YXRlKA0KICAgICAgJzk1JSBjcmVkaWJsZSBpbnRlcnZhbCcgPSBzdHJfYygNCiAgICAgICAgcm91bmQoLlssImwtOTUlIENJIl0sMiksIHJvdW5kKC5bLCJ1LTk1JSBDSSJdLDIpLA0KICAgICAgICBzZXAgPSAiIC0tICIgIyBlbi1kYXNoDQogICAgICAgICksDQogICAgICBFc3RpbWF0ZXMgPSByb3VuZChwb3N0Lm1lYW4sIDIpLA0KICAgICAgUCA9IHJvdW5kKHBNQ01DLCAzKQ0KICAgICAgKSAlPiUNCiAgICBtdXRhdGUoc2lnbmlmaWNhbmNlID0gaWZlbHNlKFAgPCAwLjA1LCAiKiIsICIiKSkgJT4lDQogICAgbXV0YXRlKA0KICAgICAgIkRlc2NyaXB0aW9uIiA9IA0KICAgICAgICBzdHJfYygiJFxcYmV0YSQgPSAiLCBFc3RpbWF0ZXMsDQogICAgICAgICAgICAgICIsIENJID0gIiwgLlssICI5NSUgY3JlZGlibGUgaW50ZXJ2YWwiXSwNCiAgICAgICAgICAgICAgIiwgUCA9ICIsIHJvdW5kKFAsIDMpLA0KICAgICAgICAgICAgICAiIikNCiAgICAgICkNCg0KfQ0KICANCiMrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrIw0KIyBTZXR0aW5nIHBsb3QgdGhlbWUgZm9yIGZvcmVzdCBwbG90cw0KIysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysjDQpmb3Jlc3R0aGVtZSA8LSB0aGVtZV9idygpICsNCiAgdGhlbWUoDQogICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLA0KICAgIGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShzaXplID0gMC40LCBjb2xvciA9ICJncmV5NTAiKSwNCiAgICBheGlzLnRpY2tzID0gZWxlbWVudF9saW5lKHNpemUgPSAwLjMsIGNvbG9yID0gImdyZXk1MCIpLA0KICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gOS41LCBjb2xvciA9ICJibGFjayIpLA0KICAgIHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLA0KICAgIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBzdHJpcC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSA5LjUsIGNvbG9yID0gImJsYWNrIikNCiAgICApDQoNCiMrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrIw0KIyBTZXR0aW5nIHBsb3QgdGhlbWUgZm9yIGZvcmVzdCBwbG90cw0KIysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysjDQpzdGFja2VkYmFydGhlbWUgPC0gdGhlbWUoDQogICAgc3RyaXAudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTMpLA0KICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMyksDQogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBwYW5lbC5ncmlkLm1ham9yLnggPSBlbGVtZW50X2JsYW5rKCksDQogICAgYXhpcy50aWNrcy54ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMSksDQogICAgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoImdyZXk5NSIpDQogICkNCg0KIysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysjDQojIFNldHRpbmcgcGxvdCB0aGVtZSBmb3IgcmVncmVzc2lvbiBzY2F0dGVycGxvdA0KIysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysjDQpyZWdyZXNzaW9udGhlbWUgPC0gICB0aGVtZV9idygpICsNCiAgICB0aGVtZSgNCiAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwNCiAgICAgIGF4aXMudGlja3MgPSBlbGVtZW50X2xpbmUoc2l6ZSA9IDAuMywgY29sb3IgPSAiZ3JleTUwIiksDQogICAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDkuNSwgY29sb3IgPSAiYmxhY2siKSwNCiAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgcGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfcmVjdChjb2xvdXIgPSAiZ3JleTUwIiwgc2l6ZSA9IDAuNyksDQogICAgICBzdHJpcC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSA5LjUsIGNvbG9yID0gImJsYWNrIikNCiAgICAgICkNCg0KIysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysjDQojIFNldHRpbmcgcGxvdCB0aGVtZSBmb3Igb3JjaGFyZCBwbG90DQojKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyMNCm9yY2hhcmR0aGVtZSA8LSAgdGhlbWVfYncoKSArDQogIHRoZW1lKA0KICAgIHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQsIGNvbG9yID0gImJsYWNrIiwgZmFjZSA9ICJpdGFsaWMiKSwNCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQsIGNvbG9yID0gImdyZXkyMCIpLA0KICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0LCBjb2xvciA9ICJibGFjayIpLA0KICAgIGxlZ2VuZC5wb3NpdGlvbiA9IGMoMC4xNSwgMC4wMDIpLA0KICAgIGxlZ2VuZC5qdXN0aWZpY2F0aW9uID0gYygwLjE1LCAwLjAwMiksDQogICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KSwNCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KSwNCiAgICBsZWdlbmQuZGlyZWN0aW9uID0gImhvcml6b250YWwiDQogICAgKQ0KDQojKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrIw0KIyBDb3JyZWN0aW5nIGVzdGltYXRlIG9mIGJpbm9taWFsIHJlZ3Jlc3Npb24NCiMrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysjDQpjMiA8LSAoMTYgKiBzcXJ0KDMpLygxNSAqIHBpKSleMg0KDQpgYGANCg0KPGRpdiBzdHlsZT0ibWFyZ2luLWJvdHRvbToxMjBweDsiPg0KPC9kaXY+DQoNCiMgSHlwb3RoZXNlcw0KDQpgYGB7cn0NCg0KdGliYmxlKA0KICBGYWN0b3JzID0gYygNCiAgICAiR2VuZXRpYyBkaXZlcmdlbmNlIiwNCiAgICAiUGhlbm90eXBpYyBkaXZlcmdlbmNlIGluIGZvY2FsIHRyYWl0IiwNCiAgICAiSW52aWFiaWxpdHkgb2YgcmVjaXByb2NhbCBoeWJyaWRzIChpLmUuIGdlbmV0aWMgaW5jb21wYXRpYmlsaXR5KSIsDQogICAgIkRpc3RyaWJ1dGlvbiBvdmVybGFwIGJldHdlZW4gcGFyZW50YWwgc3BlY2llcyIsDQogICAgIkNyb3NzaW5nIGRpcmVjdGlvbiAocGFyZW50LW9mLW9yaWdpbiBlZmZlY3QpIiwNCiAgICAiU2V4LWRldGVybWluYXRpb24gc3lzdGVtIChtYWxlIGhldGVyb2dhbWV0eSB2cy4gZmVtYWxlIGhldGVyb2dhbWV0eSkiLA0KICAgICJJbnRlcmFjdGlvbiBiZXR3ZWVuIGNyb3NzaW5nIGRpcmVjdGlvbiBhbmQgc2V4LWRldGVybWluYXRpb24gc3lzdGVtIiwNCiAgICAiVHJhaXQgdHlwZSAoc291bmQgdHJhaXQgdnMuIG1vcnBob2xvZ3kpIg0KICAgICksDQogICdIeXBvdGhldGljYWwgZWZmZWN0IGZvciBub3ZlbHR5IGluIHBoZW5vdHlwaWMgbWVhbnMnID0gYygNCiAgICAiSW5jcmVhc2UuIFBvc2l0aXZlbHkgY29ycmVsYXRlIHdpdGggdGhlIGdlbmV0aWMgZGl2ZXJnZW5jZSBhdCBwaGVub3R5cGUtZGV0ZXJtaW5pbmcgbG9jaSB0aGF0IGluY3JlYXNlIHBoZW5vdHlwaWMgbm92ZWx0eSB0aHJvdWdoIG5vdmVsIGFsbGVsaWMgaW50ZXJhY3Rpb25zIChpLmUuIG92ZXIvdW5kZXJkb21pbmFuY2UsIGRvbWluYW5jZSwgYW5kIGVwaXN0YXNpcykgW0BMYW1rZXkxOTk5OyBAUmllc2ViZXJnMTk5OV0iLA0KICAgICJJbmNyZWFzZS4gSW5kaWNhdGVzIHRoZSBnZW5ldGljIGRpdmVyZ2VuY2UgYXQgcXVhbnRpdGF0aXZlIHRyYWl0IGxvY2kgKFFUTCkgdGhhdCBlbmhhbmNlcyBwaGVub3R5cGljIG5vdmVsdHkgW0BMYW1rZXkxOTk5XSIsDQogICAgIlJlZHVjZXMgdHJhaXQgc2l6ZSBieSBvdXRicmVlZGluZyBkZXByZXNzaW9uIiwNCiAgICAiSW5jcmVhc2UuIFJlaW5mb3JjZW1lbnQgaW4gcmFuZ2Ugb3ZlcmxhcHBpbmcgc3BlY2llcyBwYWlycyBkaXZlcmdlcyBRVEwgdG8gZGV2ZWxvcCBiZWhhdmlvcmFsIGlzb2xhdGlvbiwgYW5kIHRodXMgZmFjaWxpdGF0ZSBwaGVub3R5cGljIG5vdmVsdHkuIiwNCiAgICAiR2Vub21pYyBpbXByaW50aW5nIGluY3JlYXNlcyBub3ZlbCBwaGVub3R5cGUgcmVzZW1ibGVzIGVpdGhlciBtb3RoZXIgb3IgZmF0aGVyIChpLmUuIHBvbGFyIG92ZXJkb21pbmFuY2UpIFtAQ29ja2V0dDE5OTZdLiIsDQogICAgIkluY3JlYXNlIGluIG1hbGUgaGV0ZXJvZ2FtZXR5LiBJbiBtYWxlIGhldGVyb2dhbWV0aWMgb3JnYW5pc21zLCBjb2FkYXB0YXRpb24gYmV0d2VlbiBzZXgtY2hyb21vc29tZSBhbmQgb3RoZXIgY2hyb21vc29tZXMgYnJlYWtzIGRvd24gaW4gRjEgbWFsZXMgW0BIYWxkYW5lMTkyMjsgQFNjaGlsdGh1aXplbjIwMTFdLiBUaGlzIGdlbmV0aWMgaW5jb21wYXRpYmlsaXR5IHJlZHVjZSB0cmFpdCBzaXplIGluIG1hbGUgaGV0ZXJvZ2FtZXRpYyBoeWJyaWRzLiIsDQogICAgIk1hbGUgaGV0ZXJvZ2FtZXRpYyBvcmdhbmlzbXMgdGVuZCB0byBleGhpYml0IG5vdmVsIHBoZW5vdHlwZSBzaW1pbGFyIHRvIGZhdGhlciBzcGVjaWVzLCBub3QgbW90aGVyIHNwZWNpZXMsIGR1ZSB0byBlZmZlY3Qgb2YgWSBjaHJvbW9zb21lLiBGZW1hbGUgaGV0ZXJvZ2FtZXRpYyBvcmdhbmlzbXMgZG8gbm90IHNob3cgc3VjaCB0cmVuZC4iLA0KICAgICJJbmNyZWFzZSBpbiBzb3VuZCBiZWNhdXNlIG9mIGxvd2VyIGhlcml0YWJpbGl0eSBjb21wYXJlZCB0byBtb3JwaG9sb2d5IFtASG9mZm1hbm4yMDE2XSINCiAgICApLA0KICBgSHlwb3RoZXRpY2FsIGVmZmVjdCBmb3IgcGhlbm90eXBpYyB2YXJpYWJpbGl0eWAgPSBjKA0KICAgICJJbmNyZWFzZS4gSW5jcmVhc2UgdmFyaWF0aW9uIGJlY2F1c2Ugb2YgaW5jcmVhc2VkIGRpdmVyc2l0eSBpbiBub3ZlbCBhbGxlbGljIGludGVyYWN0aW9ucyBhdCBwaGVub3R5cGUgZGV0ZXJtaW5pbmcgbG9jaSBbQEVkbWFuZHMxOTk5XTsgaW5jcmVhc2UgdmFyaWF0aW9uIGJ5IGRhbWFnaW5nIGRldmVsb3BtZW50YWwgc3RhYmlsaXR5LCB0aHJvdWdoIGdlbmV0aWMgaW5jb21wYXRpYmlsaXR5IFtATGVybmVyMTk1NDsgQEFsaWJlcnQyMDAzXS4iLA0KICAgICJJbmNyZWFzZS4gSW5jcmVhc2VzIGRpdmVyc2l0eSBpbiBub3ZlbCBhbGxlbGljIGludGVyYWN0aW9ucyBhdCBRVEwgW0BFZG1hbmRzMTk5OV0iLA0KICAgICJSZWR1Y2UuIExldGhhbCBhbGxlbGljIGludGVyYWN0aW9ucyByZWR1Y2UgZ2VuZXRpYyBkaXZlcnNpdHkgb2Ygc3Vydml2aW5nIGh5YnJpZHMiLA0KICAgICJSZWR1Y2UuIFJlaW5mb3JjZW1lbnQgcmVkdWNlcyBpbnRyYXNwZWNpZmljIHZhcmlhdGlvbiBhdCBRVEwsIGFuZCB0aHVzIGRpbWluaXNoIGdlbmV0aWMgZGl2ZXJzaXR5IG9mIEYxIGh5YnJpZHMgYXQgUVRMIiwNCiAgICAiTm90IHNwZWNpZmllZCIsDQogICAgIkluY3JlYXNlIGluIG1hbGUgaGV0ZXJvZ2FtZXR5LiBSZWR1Y2VkIGRldmVsb3BtZW50YWwgc3RhYmlsaXR5IGluY3JlYXNlcyBwaGVub3R5cGljIHZhcmlhYmlsaXR5IG9mIGhldGVyb2dhbWV0aWMgRjEgbWFsZXMiLA0KICAgICJOb3Qgc3BlY2lmaWVkIiwNCiAgICAiTm90IHNwZWNpZmllZCINCiAgICApDQogICkgJT4lIA0KICBrYWJsZSgiaHRtbCIsIGNhcHRpb24gPSAiVGFibGUgUzEuIEh5cG90aGVzZXMgZm9yIHBoZW5vdHlwaWMgbm92ZWx0eSBhbmQgdmFyaWFiaWxpdHkgb2YgRjEgaHlicmlkcyIpICU+JSANCiAga2FibGVfc3R5bGluZygic3RyaXBlZCIsIHBvc2l0aW9uID0gImxlZnQiKSAlPiUgDQogIHNjcm9sbF9ib3god2lkdGggPSAiMTAwJSIsIGhlaWdodCA9ICI1MDBweCIpDQoNCmBgYA0KDQo8ZGl2IHN0eWxlPSJtYXJnaW4tYm90dG9tOjEyMHB4OyI+DQo8L2Rpdj4NCg0KIyBGZW1hbGUgcHJlZmVyZW5jZSBkYXRhDQoNCg0KYGBge3J9DQoNCnRpYmJsZSgNCiAgVGF4b24gPSBjKA0KICAgICJBbnVyYTogdHJlZSBmcm9nICgqSHlsYSopIiwNCiAgICAiRGlwdGVyYTogZnJ1aXQgZmx5ICgqRHJvc29waGlsYSopIiwNCiAgICAiT3J0aG9wdGVyYTogYnVzaGNyaWNrZXQgKCpFcGhpcHBpZ2VyKikiLA0KICAgICJPcnRob3B0ZXJhOiBncmFzc2hvcHBlciAoKkNob3J0aGlwcHVzKikiLA0KICAgICJPcnRob3B0ZXJhOiBncmFzc2hvcHBlciAoKkNob3J0aGlwcHVzKikiLA0KICAgICJPcnRob3B0ZXJhOiBncmFzc2hvcHBlciAoKkNob3J0aGlwcHVzKikiLA0KICAgICJPcnRob3B0ZXJhOiBIYXdhaWlhbiBjcmlja2V0ICgqTGF1cGFsYSopIg0KICAgICksDQogIGBQYXJlbnRhbCBzcGVjaWVzYCA9IGMoDQogICAgIipILiBjaHJ5c29zY2VsaXMqIMOXICpILiBmZW1vcmFsaXMqIiwNCiAgICAiKkQuIHZpcmlsaXMqIGZlbWFsZSDDlyAqRC4gbW9udGFuYSogbWFsZSIsDQogICAgIipFLiBlcGhpcHBpZ2VyKiBwb2x5c3lsbGFiaWMgZm9ybSANCiAgICDDlyAqRS4gZXBoaXBwaWdlciogbW9ub3N5bGxhYmljIGZvcm0iLA0KICAgICIqQy4gYnJ1bm5ldXMqIMOXICpDLiBqYWNvYnNpKiIsDQogICAgIipDLiBiaWd1dHR1bHVzKiDDlyAqQy4gQnJ1bm5ldXMqIiwNCiAgICAiKkMuIHBhcmFsbGVsdXMqIMOXICpDLiBNb250YW51cyoiLA0KICAgICIqTC4ga29oYWxlbnNpcyogw5cgKkwuIFBhcmFuaWdyYSoiDQogICAgKSwNCiAgYFJlY2lwcm9jYWwgY3Jvc3NgID0gYygiVmlhYmxlIiwgIkludmlhYmxlIiwgcmVwKCJWaWFibGUiLCA1KSksDQogIFJlc3VsdHMgPSBjKA0KICAgICIqKkRvbWluYW5jZSoqLiBCb3RoIHJlY2lwcm9jYWwgaHlicmlkcyBwcmVmZXJyZWQgaHlicmlkcyBvdmVyIG9uZSBwYXJlbnRhbCBzcGVjaWVzIGJ1dCBub3Qgb3ZlciB0aGUgb3RoZXIgcGFyZW50YWwgc3BlY2llcyIsDQogICAgIioqTWF0ZXJuYWwgLyBwYXRlcm5hbCBpbmhlcml0YW5jZSoqLiBSZXNlbWJsZWQgbW90aGVyIGluIHRoZWlyIHJlY2VwdGl2aXR5LCBidXQgcmVzZW1ibGVkIGZhdGhlciBpbiB0aGVpciBzb25nIHJlcXVpcmVtZW50IiwNCiAgICAiKipBZGRpdGl2ZSoqLiBJbnRlcm1lZGlhdGUgbWF0ZSBwcmVmZXJlbmNlcyB3aXRob3V0IGEgbGFyZ2UgZGlmZmVyZW5jZSBiZXR3ZWVuIHJlY2lwcm9jYWwgY3Jvc3NlcyIsDQogICAgIioqRG9taW5hbmNlIGFuZCBwYXRlcm5hbCBpbmhlcml0YW5jZSoqLiBCb3RoIHJlY2lwcm9jYWwgaHlicmlkcyBwcmVmZXJyZWQgb25lIHBhcmVudGFsIHNwZWNpZXMgb3ZlciB0aGVtc2VsdmVzLiBQcmVmZXJlbmNlIGZ1bmN0aW9uIHJlc2VtYmxlcyB0aGF0IG9mIHRoZSBmYXRoZXIiLA0KICAgICIqKkFkZGl0aXZlIGFuZCBkb21pbmFuY2UqKi4gU2V2ZXJhbCBjb21wb25lbnRzIG9mIHByZWZlcmVuY2Ugc2hvd2VkIGRvbWluYW5jZSwgYnV0IG90aGVyIGNvbXBvbmVudHMgc2hvd2VkIGFkZGl0aXZlIGluaGVyaXRhbmNlLiBObyBtYXRlcm5hbC9wYXRlcm5hbCBpbmhlcml0YW5jZS4iLA0KICAgICIqKk5vdmVsIHByZWZlcmVuY2UqKi4gQm90aCByZWNpcHJvY2FsIGh5YnJpZHMgZGlkIG5vdCBkaXNjcmltaW5hdGUgYmV0d2VlbiBtYWxlcyBvZiB0d28gcGFyZW50YWwgc3BlY2llcyIsDQogICAgIioqQWRkaXRpdmUqKi4gSW50ZXJtZWRpYXRlIHByZWZlcmVuY2UgZnVuY3Rpb24sIHdoaWNoIHdhcyBzaW1pbGFyIHRvIHJlY2lwcm9jYWwgaHlicmlkcywgcmVzdWx0aW5nIGluIHByZWZlcmVuY2UgZm9yIGh5YnJpZHMiDQogICAgKSwNCiAgUmVmZXJlbmNlID0gYygNCiAgICAiQERvaGVydHkxOTg0IiwgIkBJc29oZXJyYW5lbjE5OTkiLCAiQFJpdGNoaWUyMDAwIiwgIkBCcmlkbGUyMDA2IiwgDQogICAgIkBHb3R0c2JlcmdlcjIwMTkiLCAiQEhvY2hraXJjaDIwMTEiLCAiQFNoYXcyMDAwIg0KICAgICkNCiAgKSAlPiUgDQogIGthYmxlKCJodG1sIiwgY2FwdGlvbiA9ICJUYWJsZSBTMi4gUHJldmlvdXNseSBkZXNjcmliZWQgZmVtYWxlIG1hdGUgcHJlZmVyZW5jZSBvZiBGMSBoeWJyaWRzIikgJT4lIA0KICBrYWJsZV9zdHlsaW5nKCJzdHJpcGVkIiwgcG9zaXRpb24gPSAibGVmdCIpICU+JSANCiAgc2Nyb2xsX2JveCh3aWR0aCA9ICIxMDAlIiwgaGVpZ2h0ID0gIjUwMHB4IikNCg0KYGBgDQoNCk9ubHkgMyBvdXQgb2YgNyBzdHVkaWVzIGRldGVjdGVkIGFkZGl0aXZlIGluaGVyaXRhbmNlIGluIGZlbWFsZSBtYXRlIHByZWZlcmVuY2UgZHVyaW5nIGh5YnJpZGl6YXRpb24sIHNob3dpbmcgdGhhdCBub24tYWRkaXRpdml0eSBwZXJ2YWRlcyBmZW1hbGUgbWF0ZSBwcmVmZXJlbmNlIG9mIEYxIGh5YnJpZHMuIERvbWluYW5jZSBhbmQgcGFyZW50LW9mLW9yaWdpbiBlZmZlY3QgKG1hdGVybmFsIC8gcGF0ZXJuYWwgaW5oZXJpdGFuY2UpIHdlcmUgZGV0ZWN0ZWQgaW4gMyBhbmQgMiBzdHVkaWVzLCByZXNwZWN0aXZlbHkuIE5vdmVsIHdlYWsgcHJlZmVyZW5jZSBhbHNvIGFwcGVhcmVkIGluIDEgc3R1ZHkuIEltcG9ydGFudGx5LCBjb21wb25lbnRzIG9mIGZlbWFsZSBwcmVmZXJlbmNlIG9mdGVuIHZhcmllZCBpbiBpbmhlcml0YW5jZSBtb2RlLCBpbmRpY2F0aW5nIHRoYXQgaW50ZWdyYXRpb24gb2YgbWF0ZSBwcmVmZXJlbmNlIGVhc2lseSBicmVha3MgZG93biBpbiBGMSBoeWJyaWRzLiBUaGlzIHN1bW1hcnkgaXMgYmFzZWQgb24gYSBub24tZXhoYXVzdGl2ZSBhbmQgbm9uLXN5c3RlbWF0aWMgcmV2aWV3Lg0KDQo8ZGl2IHN0eWxlPSJtYXJnaW4tYm90dG9tOjEyMHB4OyI+DQo8L2Rpdj4NCg0KIyBEYXRhIGRlc2NyaXB0aW9uDQo8ZGl2IHN0eWxlPSJtYXJnaW4tYm90dG9tOjcwcHg7Ij4NCjwvZGl2Pg0KDQpMaXN0IG9mIHByaW1hcnkgc3R1ZGllcyBpbmNsdWRlZA0KDQpgYGB7ciwgcmVzdWx0cyA9ICdhc2lzJ30NCg0KcmVhZC54bHN4KA0KICAiLi4vZGF0YS9vcmlnaW5hbC5kYXRhLnhsc3giLCBzaGVldCA9ICJQcmltYXJ5LnN0dWRpZXMiDQogICMgU2FtZSBkYXRhIGlzIGFsc28gc2F2ZWQgYXMgIi4uL2RhdGEvb3JpZ2luYWwuZGF0YS5QcmltYXJ5LnN0dWRpZXMudHh0Ig0KICApICU+JQ0KICBhcnJhbmdlKEZpcnN0LmF1dGhvciwgWWVhcikgJT4lDQogIGthYmxlKCJodG1sIikgJT4lIGthYmxlX3N0eWxpbmcoInN0cmlwZWQiLCBwb3NpdGlvbiA9ICJsZWZ0IikgJT4lIA0KICBzY3JvbGxfYm94KHdpZHRoID0gIjEwMCUiLCBoZWlnaHQgPSAiNTAwcHgiKQ0KICANCmBgYA0KDQoqKlN0dWR5Lm5hbWUqKjogSW5jbHVkaW5nIGF1dGhvciBuYW1lKHMpIGFuZCBwdWJsaXNoZWQgeWVhcg0KDQo8ZGl2IHN0eWxlPSJtYXJnaW4tYm90dG9tOjcwcHg7Ij4NCjwvZGl2Pg0KDQojIyBUYWJsZSBvZiB0aGUgZGF0YXNldA0KDQpEYXRhIG9mIHBoZW5vdHlwZSB1c2VkIGluIHRoaXMgc3R1ZHkuDQoNCmBgYHtyLCByZXN1bHRzID0gJ2FzaXMnfQ0KDQojIyBQaGVub3R5cGUgZGF0YSAjIw0KcGhlbm8gPC0gcmVhZC54bHN4KA0KICAgICIuLi9kYXRhL29yaWdpbmFsLmRhdGEueGxzeCIsIHNoZWV0ID0gIlBoZW5vdHlwZSINCiAgICAjIFNhbWUgZGF0YSBpcyBhbHNvIHNhdmVkIGFzICIuLi9kYXRhL29yaWdpbmFsLmRhdGEuUGhlbm90eXBlLnR4dCINCiAgICApICU+JQ0KICAjIEV4Y2x1ZGluZyBkYXRhIHdpdGhvdXQgYW55IHBhcmVudCBkYXRhDQogIGRyb3BfbmEoY29udGFpbnMoIlNELnNwIikpICU+JQ0KICAjIHRvIG51bWVyaWMNCiAgbXV0YXRlX2F0KA0KICAgIHZhcnMoY29udGFpbnMoIk1uIikgfCBjb250YWlucygiU0QiKSB8IE4uc3AxOk4uc3AyKSwgDQogICAgYXMubnVtZXJpYw0KICAgICkgJT4lDQogICMgZGVsZXRlIG9ic2VydmF0aW9uIHdpdGggbmVnYXRpdmUgbWVhbiB0cmFpdCB2YWx1ZQ0KICBmaWx0ZXIoTW4uc3AxID4gMCAmIE1uLnNwMiA+IDAgJiBob21vbG9nb3VzID09ICJZZXMiKSAlPiUgICANCiAgIyBjYWxjdWxhdGUgcGhlbm90eXBpYyBkaWZmZXJlbmNlIGJldHdlZW4gcGFyZW50YWwgc3BlY2llcw0KICBtdXRhdGUoDQogICAgUGhlbm8uZGl2ZXJnZW5jZSA9IGFicyhsb2coTW4uc3AxL01uLnNwMikpDQogICAgKSAlPiUNCiAgbXV0YXRlX2F0KHZhcnMoY29udGFpbnMoInBoZW5vLmRpdiIpKSwgc2NhbGUpICU+JQ0KICAjIGRlc2NyaWJlIHdoZXRoZXIgZnVsbCBjcm9zcyBvciBub3QNCiAgbXV0YXRlKA0KICAgIFJlY2lwcm9jYWwgPSBpZmVsc2UoDQogICAgICBpcy5uYShNbi5oeWIxMiAmIE1uLmh5YjIxKSwgDQogICAgICAiSW52aWFibGUiLCAiVmlhYmxlIg0KICAgICAgKQ0KICAgICkNCg0KIyBtYWtpbmcgYSBzY3JvbGxhYmxlIHRhYmxlDQprYWJsZShwaGVubywgImh0bWwiKSAlPiUga2FibGVfc3R5bGluZygic3RyaXBlZCIsIHBvc2l0aW9uID0gImxlZnQiKSAlPiUgDQogICAgc2Nyb2xsX2JveCh3aWR0aCA9ICIxMDAlIiwgaGVpZ2h0ID0gIjUwMHB4IikNCg0KYGBgDQoNCioqU3R1ZHkuSUQqKjogSUQgb2Ygc3R1ZGllcw0KDQoqKlN0dWR5Lm5hbWUqKjogSW5jbHVkaW5nIGF1dGhvciBuYW1lKHMpIGFuZCBwdWJsaXNoZWQgeWVhcg0KDQoqKlNvdXJjZSoqOiBTb3VyY2Ugb2YgcGhlbm90eXBjIGRhdGEgaW4gdGhlIHByaW1hcnkgc3R1ZGVzDQoNCioqQ3Jvc3MuSUQqKjogUGFyZW50YWwgc3BlY2llcyB1c2VkIGluIHRoZSBjcm9zc2luZyBleHByZWltZW50cy4gRGlzdGluZ3Vpc2hlcyBpbnRyYXNwZWNpZmljIHBvcHVsYXRpb25zLg0KDQoqKkdlbm51cyoqOiBTdHVkaWVkIGdlbnVzDQoNCioqc3AxLm5hbWUqKiBhbmQgKipzcDIubmFtZSoqOiBDcm9zc2VkIHNwZWNpZXMuIE9yZGVyZWQgYWxwaGFiZXRpY2FsbHkuDQoNCioqc3BlY2llcy5wYWlyKio6IFBhcmVudGFsIHNwZWNpZXMgdXNlZCBpbiB0aGUgY3Jvc3NpbmcgZXhwcmVpbWVudHMuIE5vdCBkaXN0aW5ndWlzY3IgaW50cmFzcGVjaWZpYyBwb3B1bGF0aW9ucy4NCg0KKipob21vbG9nb3VzKio6IE1lYXN1cmVkIHRyYWl0cyBhcmUgaG9tb2xvZ291cyBhY3Jvc3MgYWxsIGNyb3NzZXMuIElmIG5vdCwgZGF0YSBoYXMgYmVlbiBleGNsdWRlZA0KDQoqKnRyYWl0LnR5cGUqKjogU291bmQgb3IgTW9ycGhvbG9neS4gVXNlZCBpbiByZWdyZXNzaW9ucyBiZWxsb3cgYXMgYSBtb2RlcmF0b3IuDQoNCioqdHJhaXQqKjogVHJhaXQgbmFtZSBkZXNjcmliZWQgaW4gcHJpbWFyeSBzdHVkaWVzDQoNCioqTW4ufioqOiBQaGVub3R5cGljIG1lYW4gb2YgZWFjaCBjcm9zcw0KDQoqKlNELn4qKjogU0Qgb2YgcGhlbm90eXBlIGluIGVhY2ggY3Jvc3MNCg0KKipTRS5+Kio6IFNFIG9mIHBoZW5vdHlwZSBpbiBlYWNoIGNyb3NzDQoNCioqUGFyZW50cy5+Kio6IE51bWJlciBvZiBwYXJlbnRzIHVzZWQgaW4gZWFjaCBjcm9zc2luZy4gVXN1YWxseSBub3QgcHJvdmlkZWQgYnkgdGhlIHByaW1hcnkgc3R1ZGllcy4NCg0KKipOLn4qKjogTnVtYmVyIG9mIGluZGl2aWR1YWxzIHdob3NlIHBoZW5vdHlwZSB3YXMgbWVhc3VyZWQNCg0KKipyZXBzLn4qKjogTnVtYmVyIG9mIG1lYXN1cmVtZW50cywgaWYgcmVwbGljYXRlZCAoZXNwZWNpYWxseSBpbiBiZWhhdmlvcmFsIHRyYWl0cykuIE5vdCB1c2VkIGluIHRoZSBhbmFseXNlcyBiZWxsb3cuDQoNCioqUGhlbm8uZGl2ZXJnZW5jZSoqOiBQaGVub3R5cGljIGRpdmVyZ2VuY2UgYmV0d2VlbiBwYXJlbnRzIGluIHRoZSBmb2NhbCB0cmFpdCwgd2hpY2ggaXMgY2FsY3VsYXRlZCBhcyBhYnNvbHV0ZSB2YWx1ZSBvZiBsb2cgcmVzcG9uc2UgcmF0aW8gKGxuUlIpIG9mIHBoZW5vdHlwaWMgbWVhbnMuIFVzZWQgaW4gcmVncmVzc2lvbnMgYmVsbG93IGFzIGEgbW9kZXJhdG9yLg0KDQo8ZGl2IHN0eWxlPSJtYXJnaW4tYm90dG9tOjcwcHg7Ij4NCjwvZGl2Pg0KDQoNClRoZSBzcGVjaWVzLWxldmVsIG1vZGVyYXRvciBkYXRhc2V0IG9mIHRoaXMgc3R1ZHkuDQoNCmBgYHtyLCByZXN1bHRzID0gJ2FzaXMnfQ0KDQptZXRhIDwtIHJlYWQueGxzeCgNCiAgICAiLi4vZGF0YS9vcmlnaW5hbC5kYXRhLnhsc3giLCBzaGVldCA9ICJTcGVjaWVzLmxldmVsLm1vZGVyYXRvcnMiDQogICAgIyBTYW1lIGRhdGEgaXMgYWxzbyBzYXZlZCBhcyAiLi4vZGF0YS9vcmlnaW5hbC5kYXRhLlNwZWNpZXMubGV2ZWwubW9kZXJhdG9ycy50eHQiDQogICAgKSAlPiUNCiAgbXV0YXRlX2F0KHZhcnMoY29udGFpbnMoImRpdmVyZ2VuY2UiKSksIGFzLm51bWVyaWMpICU+JQ0KICAjIExvZ2FsaXplIGdlbmV0aWMgZGl2ZXJnZW5jZQ0KICBtdXRhdGVfYXQodmFycyhjb250YWlucygiZGl2ZXJnZW5jZSIpKSwgbG9nMTApDQoNCiMgbWFraW5nIGEgc2Nyb2xsYWJsZSB0YWJsZQ0Ka2FibGUobWV0YSwgImh0bWwiKSAlPiUga2FibGVfc3R5bGluZygic3RyaXBlZCIsIHBvc2l0aW9uID0gImxlZnQiKSAlPiUgDQogICAgc2Nyb2xsX2JveCh3aWR0aCA9ICIxMDAlIiwgaGVpZ2h0ID0gIjUwMHB4IikNCiAgDQoNCiMrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrDQojIENvbWJpbmUgcGhlbm90eXBpYyBkYXRhIGFuZCBtb2RlcmF0b3JzIGRhdGENCiMrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrDQpvcmlnaW5hbC5kYXQgPC0gbGVmdF9qb2luKHBoZW5vLCBtZXRhKQ0KIyBhZGQgdW5pcXVlIElEIGZvciBlYWNoIGVmZmVjdCBzaXplIChyb3cpDQpvcmlnaW5hbC5kYXQkRVMuSUQgPC0gcGFzdGUoIkVTIixzcHJpbnRmKCIlMDNkIixjKDE6ZGltKG9yaWdpbmFsLmRhdClbMV0pKSwgc2VwPSIiKQ0KDQojICMrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysNCiMgcHJpbnQoIlNjYWxpbmciKQ0KIyAjKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrDQojIHByaW50KCJQaGVub3R5cGljIGRpdmVyZ2VuY2UgcmF0aW8iKQ0KIyBhdHRyaWJ1dGVzKHBoZW5vJFBoZW5vLmRpdmVyZ2VuY2UpDQojIHByaW50KCJNaW5pbXVtIHNjYWxlZCB2YWx1ZSIpDQojIG1pbihwaGVubyRQaGVuby5kaXZlcmdlbmNlKQ0KIyBwcmludCgiTWF4aW11bSBzY2FsZWQgdmFsdWUiKQ0KIyBtYXgocGhlbm8kUGhlbm8uZGl2ZXJnZW5jZSkNCg0KYGBgDQoNCioqUmVjaXByb2NhbCoqOiBWaWFiaWxpdHkgb2YgcmVjaXByb2NhbCBoeWJyaWRzLCB3aXRoIHR3byBsZXZlbHMgLSAqVmlhYmxlKiBvciAqSW52aWFibGUqDQoNCioqR2VuZXQuZGl2ZXJnZW5jZSoqOiBOYXR1cmFsIGxvZ2FyaXRobSBvZiBnZW5ldGljIGRpc3RhbmNlIGF0IG10RE5BIENPSSByZWdpb24gKD40NTBicCkuDQoNCioqRGlzdHJpYnV0aW9uKio6IERpc3RyaWJ1dGlvbiBvdmVybGFwIC0gKkFsbG9wYXRyeSogb3IgKk92ZXJsYXAqDQoNCioqSGV0ZXJvLnNleCoqOiBIZXRlcm9nYW1ldGljIHNleCAtICpGZW1hbGUqIChaVyBhbmQgWjApIG9yICpNYWxlKiAoWFkgYW5kIFgwKQ0KDQoNCjxkaXYgc3R5bGU9Im1hcmdpbi1ib3R0b206NzBweDsiPg0KPC9kaXY+DQojIyBTcGVjaWVzIGNvbXBvc2l0aW9uDQpgYGB7ciwgcmVzdWx0cyA9ICdhc2lzJ30NCg0KIysrKysrKysrKysrKysrKysrKysrKyMNCiMgUGh5bG9nZW55DQojKysrKysrKysrKysrKysrKysrKysrIw0KDQojIHNwZWNpZXMgcGFpcnMgZGF0YSANCnRheGEgPC0gbWV0YSAlPiUNCiAgc2VsZWN0KC1Dcm9zcy5JRCkgJT4lDQogIGRpc3RpbmN0X2FsbCgua2VlcF9hbGwgPSBUUlVFKSAlPiUNCiAgbXV0YXRlX2F0KCJ0YXhhIiwgYXMuZmFjdG9yKQ0KDQojIG1hdGNoaW5nIG5hbWVzIGZyb20gb3BlbiB0cmVlIHRheG9ub215DQpvcmRlciA8LSB0bnJzX21hdGNoX25hbWVzKA0KICBuYW1lcyA9IGxldmVscyh0YXhhJHRheGEpICU+JQ0KICAgIHN0cl9yZXBsYWNlX2FsbCgiXyIsICIgIiksIA0KICBjb250ZXh0X25hbWUgPSAiQW5pbWFscyINCiAgKQ0KDQojIHdoaWNoIG5hbWVzIHJldHVybiBtb3JlIHRoYW4gMSBtYXRjaD8NCm11bHRpbWF0Y2ggPC0gb3JkZXIkb3R0X2lkW29yZGVyJG51bWJlcl9tYXRjaGVzICE9IDFdDQojIGluc3BlY3Qob3JkZXIsIG90dF9pZCA9IG11bHRpbWF0Y2hbMV0pICMgQW51cmEsIGNvbmZpcm1lZCBhZG9wdGVkIG90dF9pZCBpcyBjb3JyZWN0DQojIGluc3BlY3Qob3JkZXIsIG90dF9pZCA9IG11bHRpbWF0Y2hbMl0pICMgTmV1cm9wdGVyYSwgY29uZmlybWVkIGFkb3B0ZWQgb3R0X2lkIGlzIGNvcnJlY3QNCg0KIyBDcmVhdGUgdGF4b25vbWljIHRyZWUNCnRyZWUgPC0gdG9sX2luZHVjZWRfc3VidHJlZShvdHRfaWRzID0gb3JkZXIkb3R0X2lkKQ0KIyBSZW1vdmUgb3R0IGlkcyBmcm9tIHRpcCBsYWJlbA0KdHJlZSR0aXAubGFiZWwgJTw+JQ0KICBzdHJpcF9vdHRfaWRzKHJlbW92ZV91bmRlcnNjb3Jlcz1UUlVFKQ0KdHJlZSR0aXAubGFiZWxbOF0gPC0gIkFudXJhIg0KDQojICMgTiBvZiBzcGVjaWVzIHBhaXJzIGF0IGVhY2ggb3JkZXINCiMgZmFjdG9yKG1ldGEuc3VtJHRheGEsIGxldmVscyA9IGFzLnZlY3Rvcih0cmVlJHRpcC5sYWJlbCkpDQoNCnBsb3QucGh5bG8gPC0gZ2d0cmVlKHRyZWUpICsgDQogIGdlb21fdGlwbGFiKA0KICAgIGdlb20gPSAiaW1hZ2UiLA0KICAgIGltYWdlID0gcGFzdGUoIi4uL2RhdGEvcGljIiwgdHJlZSR0aXAubGFiZWwsICJwbmciLCBzZXAgPSAiLiIpLCANCiAgICBzaXplID0gMC4xLCBvZmZzZXQgPSAzLCBoanVzdCA9IDENCiAgICApICsNCiAgZ2VvbV90aXBsYWIoDQogICAgZ2VvbSA9ICJ0ZXh0IiwgIA0KICAgIGxhYmVsID0gdHJlZSR0aXAubGFiZWwsIA0KICAgIGFsaWduID0gMSwgc2l6ZSA9IDMNCiAgICApICsNCiAgeGxpbShOQSwgNykNCg0KIyBpbWFnZXMgZnJvbSBwaHlsb3BpYyAjICAgIA0KIyBMZXBpZG9wdGVyYSAoZ2VudXMgQ2F0b2NhbGEpICJjMjI0YWJmZC1lZTM5LTQ5MjMtOThlNS1jMjYwNmRjYzU2Y2IiLCANCiMgRGlwdGVyYSAoRHJvc29waGlsYSkgIjBjZDZjYzlmLTY4M2MtNDcwZS1hNGE2LTNiNjhiZWI4MjZmYSINCiMgT3J0aG9wdGVyYSAoY3JpY2tldCkgImI4MGQ4MzBiLTE1NWEtNGNhNS05MTE5LTlhOWZkZTAxOWNjNiINCiMgUm9kZW50aWEgKG1vdXNlKSwgZHJhd24gYnkgRGF2aWQgTGlhbyAiMGY2YWYzZDgtNDlkMi00ZDc1LThlZGYtMDg1OTgzODdhZmRlIg0KIyBBdmVzIChRdWFpbCkgIjQyZjg1YTJiLTc1MTctNDM5YS04ZGMzLWI3NDVhMzVjMDM1ZCINCiMgQW51cmEgKGdlbnVzIEh5bGEpICJBMjJEMzUzRC1CMDQ1LTQwNDQtOTQzMi04RjM0MEI5QTMxMDQiLCANCiMgQ2ljaGxpZm9ybWVzIChOaWxlIHRpbGFwaWEpLCBkcmF3biBieSBNaWx0b24gVGFuICI4NGM3ZTY3Mi0yNTkzLTQ0YTYtYTgwNy1jZmZiZDMxNTZjYzUiIA0KDQoNCiMrKysrKysrKysrKysrKysrKysrKysjDQojIFN1bW1hcnkgDQojKysrKysrKysrKysrKysrKysrKysrIw0KDQpzdW1tYXJ5IDwtIG9yaWdpbmFsLmRhdCAlPiUNCiAgZ3JvdXBfYnkodGF4YSkgJT4lDQogIHN1bW1hcmlzZSgNCiAgICAnU3BlY2llcyBwYWlyJyA9IGxlbmd0aCh1bmlxdWUoc3BlY2llcy5wYWlyKSksDQogICAgJ09ic2VyLSB2YXRpb24nID0gbGVuZ3RoKHVuaXF1ZShFUy5JRCkpLA0KICAgIFN0dWR5ID0gbGVuZ3RoKHVuaXF1ZShTdHVkeS5JRCkpDQogICAgKSAlPiUNCiAgIyBPcmRlciB0YXhvbiBzbyB0aGF0IG1hdGNoIHdpdGggcGh5bG9nZW5ldGljIHRyZWUgdG9wb2xvZ3kNCiAgd2l0aGluKHRheGEgPC0gb3JkZXJlZCh0YXhhLCBsZXZlbHMgPSBjKCJOZXVyb3B0ZXJhIiwgIkNvbGVvcHRlcmEiLCAiRGlwdGVyYSIsICJMZXBpZG9wdGVyYSIsICJPcnRob3B0ZXJhIiwgIkF2ZXMiLCAiUm9kZW50aWEiLCAiQW51cmEiLCAiQ2ljaGxpZm9ybWVzIikpKQ0KDQoNCiMjIFRhYmxlICMjIw0Kc3VtbWFyeSAlPiUNCiAgc3VtbWFyaXNlX2lmKGlzLm51bWVyaWMsIHN1bSkgJT4lDQogICAgbXV0YXRlKHRheGEgPSAiVG90YWwiKSAlPiUNCiAgYmluZF9yb3dzKHN1bW1hcnksIC4pICU+JQ0KICBrYWJsZSgiaHRtbCIsIGRpZ2l0cyA9IDMpICU+JSANCiAga2FibGVfc3R5bGluZygic3RyaXBlZCIsIHBvc2l0aW9uID0gImxlZnQiKQ0KDQojIyBQbG90ICMjIw0KcGxvdC5zdW0gPC0gZ2dwbG90KA0KICAjIE1ha2UgdGlkeSBzdW1tYXJ5IGRhdGENCiAgc3VtbWFyeSAlPiUNCiAgZ2F0aGVyKGtleSA9IG1ldHJpY3MsIHZhbHVlID0gTiwgLWModGF4YSkpICU+JQ0KICAjIE9yZGVyIG1ldHJpY3MNCiAgd2l0aGluKA0KICAgIG1ldHJpY3MgPC0gb3JkZXJlZCgNCiAgICAgIG1ldHJpY3MsDQogICAgICBsZXZlbHMgPSBjKCJTdHVkeSIsICJTcGVjaWVzIHBhaXIiLCAiT2JzZXItIHZhdGlvbiIpDQogICAgICApDQogICAgKSwgDQogIGFlcyh4ID0gIiIsIHkgPSBOLCBmaWxsID0gdGF4YSkpICsNCiAgZ2VvbV9iYXIod2lkdGggPSAxLCBzdGF0ID0gImlkZW50aXR5IikgKw0KICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlBhaXJlZCIpICsNCiAgZmFjZXRfd3JhcCgNCiAgICBzY2FsZSA9ICJmcmVlIiwgIm1ldHJpY3MiLA0KICAgICMgc3RyaXAgdGV4dCBpbnRvIHR3byBsaW5lcw0KICAgIGxhYmVsbGVyID0gbGFiZWxfd3JhcF9nZW4od2lkdGggPSA4KQ0KICAgICkgKw0KICB4bGFiKCIiKSArDQogIHN0YWNrZWRiYXJ0aGVtZSArDQogIHRoZW1lKA0KICAgIHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwNCiAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQpDQogICAgKQ0KDQojKysrKysrKysrKysrKysrKysjDQojIENvbWJpbmUgZmlndXJlcw0KIysrKysrKysrKysrKysrKysrIw0KIyBwbG90LmFsbCA8LSBwbG90LnBoeWxvICsgcGxvdC5zdW0NCnBsb3Quc3VtDQojIHNhdmUoDQojICAgcGxvdCA9IHBsb3QuYWxsLCANCiMgICBmaWxlID0gIi4uL0FuYWx5c2lzL2RhdGEuc3ZnIiwgaGVpZ2h0ID0gNSwgd2lkdGggPSA4LjUNCiMgICApDQoNCmBgYA0KKipGaWd1cmUgMWEqKiANCg0KPGRpdiBzdHlsZT0ibWFyZ2luLWJvdHRvbTo3MHB4OyI+DQo8L2Rpdj4NCg0KIyMgVGF4b25vbWljIGRpc3RyaWJ1dGlvbiBvZiBzcGVjaWVzLWxldmVsIG1vZGVyYXRvciBzdGF0dXMNClN1bW1hcmlzZWQgZGlzdHJpYnV0aW9ucyBvZiBjYXRlZ29yaWNhbCBzcGVjaWVzLWxldmVsIG1vZGVyYXRvcnMgaW4gZWFjaCB0YXhvbiAob3JkZXIpLg0KYGBge3IsIHJlc3VsdHM9J2FzaXMnfQ0KDQptZXRhdmFycyA8LSBjKCJSZWNpcHJvY2FsIiwgIkRpc3RyaWJ1dGlvbiIsICJIZXRlcm8uc2V4IikNCg0KbWV0YS51bmlxdWUgPC0gb3JpZ2luYWwuZGF0ICU+JQ0KICBkaXN0aW5jdF9hdCgic3BlY2llcy5wYWlyIiwgLmtlZXBfYWxsID0gVFJVRSkgJT4lDQogIG11dGF0ZV9hdChtZXRhdmFycywgYXMuZmFjdG9yKQ0KDQptZXRhLmFsbC5zcCA8LSBtZXRhLnVuaXF1ZSAlPiUgDQogIGdyb3VwX2J5KHRheGEpICU+JQ0KICBzdW1tYXJpc2UoVG90YWwgPSBsZW5ndGgoc3BlY2llcy5wYWlyKSkgDQoNCmZvciAoaSBpbiBtZXRhdmFycykgew0KICANCiAgYmluZF9yb3dzKA0KICAgICMgQXQgZWFjaCB0YXhvbg0KICAgIG1ldGEudW5pcXVlICU+JSANCiAgICAgIGdyb3VwX2J5XygidGF4YSIsIGkpICU+JQ0KICAgICAgc3VtbWFyaXNlKHNwZWNpZXMgPSBsZW5ndGgoc3BlY2llcy5wYWlyKSkNCiAgICAsDQogICAgIyBBbGwgdGF4b24NCiAgICBtZXRhLnVuaXF1ZSAlPiUgDQogICAgICBncm91cF9ieV8oaSkgJT4lDQogICAgICBzdW1tYXJpc2Uoc3BlY2llcyA9IGxlbmd0aCh1bmlxdWUoc3BlY2llcy5wYWlyKSkpICU+JSANCiAgICAgIG11dGF0ZSh0YXhhID0gIlRvdGFsIikNCiAgICApICU+JQ0KICAgIHVuZ3JvdXAgJT4lDQogICAgc3ByZWFkKGtleSA9IGksIHZhbHVlID0gInNwZWNpZXMiKSAlPiUNCiAgICBtdXRhdGVfYWxsKH5yZXBsYWNlKC4sIGlzLm5hKC4pLCAwKSkgJT4lICMgcmVwbGFjZSBOQSBieSAwDQogICAgYXMuZGF0YS5mcmFtZSAlPiUNCiAgICAjIEFsbCBzcGVjaWVzIHBhaXIgYXQgZWFjaCB0YXhvbjogc3VtbWluZyBjb2x1bW5zDQogICAgbXV0YXRlKFRvdGFsID0gcm93U3VtcyguWzI6KDErbmxldmVscyhtZXRhLnVuaXF1ZVssIGldKSldKSkgJT4lDQogICAgIyBDYWxjICUgb2YgbGV2ZWwgMiAoaS5lLiBtYWxlIGhldGVybywgLi4uKQ0KICAgIG11dGF0ZSgnJScgPSByb3VuZCguWzNdL1RvdGFsKjEwMCwgMSkpICU+JQ0KICAgIHJlbmFtZSghIXBhc3RlMChsZXZlbHMobWV0YS51bmlxdWVbLCBpXSlbMl0sICIlIikgOj0gIiUiKSAlPiUNCiAgICAjIFRhYmxlIG91dHB1dA0KICAgIGthYmxlKCJodG1sIiwgZGlnaXRzID0gMywgY2FwdGlvbiA9IGkpICU+JSANCiAgICBrYWJsZV9zdHlsaW5nKCJzdHJpcGVkIiwgcG9zaXRpb24gPSAibGVmdCIpICU+JQ0KICAgIHByaW50KCkNCg0KfSAgDQoNCmBgYA0KDQo8ZGl2IHN0eWxlPSJtYXJnaW4tYm90dG9tOjcwcHg7Ij4NCjwvZGl2Pg0KDQojIyBEYXRhIHVzZWQgaW4gbWV0YS1yZWdyZXNzaW9uIChhbGwgbWV0YWRhdGEgYXZhaWxhYmxlKQ0KYGBge3J9DQoNCmZ1bGxfam9pbigNCiAgIyBBbGwgc3BlY2llcyBwYWlyDQogIG9yaWdpbmFsLmRhdCAlPiUNCiAgICBzZWxlY3QoYygidGF4YSIsICJzcGVjaWVzLnBhaXIiKSkgJT4lDQogICAgZGlzdGluY3RfYWxsKCkgJT4lDQogICAgZ3JvdXBfYnkodGF4YSkgJT4lDQogICAgc3VtbWFyaXNlKCdBbGwgc3BlY2llcycgPSBsZW5ndGgoc3BlY2llcy5wYWlyKSksDQogICMgU3BlY2llcyBwYWlyIHVzZWQgaW4gbWV0YS1yZWdyZXNzaW9uDQogIG9yaWdpbmFsLmRhdCAlPiUNCiAgICBmaWx0ZXIoIWlzLm5hKHNleC5kZXRlcm1pbmF0aW9uKSwgIWlzLm5hKEdlbmV0LmRpdmVyZ2VuY2UpKSAlPiUNCiAgICBzZWxlY3QoYygidGF4YSIsICJzcGVjaWVzLnBhaXIiKSkgJT4lDQogICAgZGlzdGluY3RfYWxsKCkgJT4lDQogICAgZ3JvdXBfYnkodGF4YSkgJT4lDQogICAgc3VtbWFyaXNlKCdNZXRhZGF0YSBhdmFpbGFibGUnID0gbGVuZ3RoKHNwZWNpZXMucGFpcikpDQogICkgJT4lDQogIG11dGF0ZV9hbGwofnJlcGxhY2UoLiwgaXMubmEoLiksIDApKSAlPiUgIyByZXBsYWNlIE5BIGJ5IDANCiAga2FibGUoImh0bWwiLCBjYXB0aW9uID0gIk51bWJlcnMgb2YgYWxsIHNwZWNpZXMgcGFpcnMsIGFuZCBzcGVjaWVzIHBhaXJzIHVzZWQgaW4gbWV0YS1yZWdyZXNzaW9uDQoiKSAlPiUgDQogIGthYmxlX3N0eWxpbmcoInN0cmlwZWQiLCBwb3NpdGlvbiA9ICJsZWZ0IikNCg0KYGBgDQpUd28gZmlzaCBhbmQgdGhyZWUgb3J0aG9wdGVyYSBzcGVjaWVzLXBhaXJzIHdlcmUgbm90IHVzZWQgaW4gbWV0YS1yZWdyZXNzaW9uIGFuZCBCYXllc2lhbiBwaHlsb2dlbmV0aWMgbWl4ZWQgbW9kZWxzIGJlY2F1c2Ugb2YgdGhlIGxhY2sgb2YgZGF0YSBmb3IgZ2VuZXRpYyBkaXN0YW5jZSBvciBzZXgtZGV0ZXJtaW5hdGlvbiBzeXN0ZW0gKGZpc2gsICpIYXBsb2Nocm9taXMgYnVydG9uaSogw5cgKkguIG51YmlsdXMqIGFuZCAqUHVuZGFtaWxpYSBueWVyZXJlaSogw5cgKlAuIHB1bmRhbWlsaWEqOyBvcnRob3B0ZXJhLCAqQ2hvcnRoaXBwdXMgcGFyYWxsZWx1cyBlcnl0aHJvcHVzKiDDlyAqQy4gcGFyYWxsZWx1cyBwYXJhbGxlbHVzKiwgKkdyeWxsdXMgYXJtYXR1cyogw5cgKkcuIHJ1YmVucyogYW5kICpMYXVwYWxhIGtvaGFsZW5zaXMqIMOXICpMLiBwYXJhbmlncmEqKS4gV2UgZGlkIG5vdCBhc3NpZ24gdmFsdWUgb2YgdGhlIGhldGVyb2dhbWV0aWMgc2V4IGluIGNpY2hsaWQgZmlzaGVzIHRoYXQgdW5kZXJnbyBmcmVxdWVudCBldm9sdXRpb25hcnkgY2hhbmdlcyBpbiBzZXgtZGV0ZXJtaW5hdGlvbiBzeXN0ZW0gW1lvc2hpZGEgZXQgYWwuIDIwMTFdKGh0dHBzOi8vZHgucGxvcy5vcmcvMTAuMTM3MS9qb3VybmFsLnBnZW4uMTAwMjIwMykuIA0KDQo8ZGl2IHN0eWxlPSJtYXJnaW4tYm90dG9tOjcwcHg7Ij4NCjwvZGl2Pg0KDQojIyBEYXRhIHByb2Nlc3NpbmcNCg0KIyMgQWxsaWduIHBhcmVudGFsIHNwZWNpZXMgYWNjb3JkaW5nIHRvIHRyYWl0IHZhbHVlcw0KDQpDdXJyZW50bHksIGRhdGFzZXQgaXMgY29tcG9zZWQgb2YgPGJyPiAgIA0KJ3NwZWNpZXMgMScgYW5kICdzcGVjaWVzIDInLCBvcmRlcmVkIGFscGhhYmV0aWNhbGx5LCBhbmQgJ2h5YnJpZDEyJyAoc3AxIG1vdGhlciAmIHNwMiBmYXRoZXIpIGFuZCAnaHlicmlkIDIxJyAoc3AyIG1vdGhlciAmIHNwMSBmYXRoZXIpPGJyPg0KPGJyPg0KVG8gaW52ZXN0aWdhdGUgcGF0ZXJuYWwgZWZmZWN0IGluIGh5YnJpZHMgdXNpbmcgZGlmZmVyZW5jZSBpbiBtZWFuIHRyYWl0IHZhbHVlIGJldHdlZW4gcmVjaXByb2NhbCBjcm9zcywgaXQncyBiZXR0ZXIgdG8gYWxsaWduIHNwZWNpZXMgd2l0aCBsYXJnZXIgdHJhaXQgdmFsdWUgKDxpPnNwTEw8c3ViPk08L3N1Yj48L2k+KSBhbmQgc21hbGxlciB2YWx1ZSAoPGk+c3BTUzxzdWI+TTwvc3ViPjwvaT4pIGluIGVhY2ggdHJhaXRzLiBOYW1lIG9mIGh5YnJpZHMgd2lsbCBiZSBjaGFuZ2VkIGFjY29yZGluZyB0byBjaGFuZ2UgaW4gbmFtZXMgb2YgcGFyZW50YWwgc3BlY2llcyAoPGk+aHlicmlkTFM8c3ViPk08L3N1Yj48L2k+ICYgPGk+aHlicmlkU0w8c3ViPk08L3N1Yj48L2k+KS4gIDxicj4NCg0KYGBge3J9DQoNCiMrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrIw0KIyBzcDEgPj0gc3AyIGluIHBoZW5vdHlwaWMgbWVhbiANCiMrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrIw0KIyBleHRyYWN0DQpzcDFzcDIubWVhbiA8LSBvcmlnaW5hbC5kYXQgJT4lDQogIGZpbHRlcihNbi5zcDEgPj0gTW4uc3AyKSAjIGZpbHRlcmluZyBhY2NvcmRpbmcgdG8gbWVhbiB0cmFpdCB2YWx1ZSBvZiBwYXJlbnRhbHMNCiMgY2hhbmdlIGNvbHVtbiBuYW1lIGZyb20gc3AxIG9yIHNwMiAtPiBzcEwgb3Igc3BTDQpuYW1lcyhzcDFzcDIubWVhbikgPC0gZ3N1YigiMSIsICJMIiwgbmFtZXMoc3Axc3AyLm1lYW4pKQ0KbmFtZXMoc3Axc3AyLm1lYW4pIDwtIGdzdWIoIjIiLCAiUyIsIG5hbWVzKHNwMXNwMi5tZWFuKSkNCg0KIysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysjDQojIHNwMSA8IHNwMiBpbiBwaGVub3R5cGljIG1lYW4gDQojKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyMNCiMgZXh0cmFjdA0Kc3Ayc3AxLm1lYW4gPC0gb3JpZ2luYWwuZGF0ICU+JQ0KICBmaWx0ZXIoTW4uc3AxIDwgTW4uc3AyKQ0KIyBjaGFuZ2UgY29sdW1uIG5hbWUgZnJvbSBzcDEgb3Igc3AyIC0+IHNwUyBvciBzcEwNCm5hbWVzKHNwMnNwMS5tZWFuKSA8LSBnc3ViKCIxIiwgIlMiLCBuYW1lcyhzcDJzcDEubWVhbikpDQpuYW1lcyhzcDJzcDEubWVhbikgPC0gZ3N1YigiMiIsICJMIiwgbmFtZXMoc3Ayc3AxLm1lYW4pKQ0KDQojKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyMNCiMgY29tYmluZSBkYXRhc2V0ICYgc29ydCBieSBFUy5JRCANCiMrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrIw0KYmluZF9yb3dzKHNwMXNwMi5tZWFuLCBzcDJzcDEubWVhbikgJT4lDQogIGFycmFuZ2UoRVMuSUQpICU+JQ0KICB3cml0ZS5jc3YoIi4uL2RhdGEvZGF0Lm1lYW4uY3N2IiwgcXVvdGU9Rixyb3cubmFtZXMgPSBGKQ0KDQpgYGANCkRhdGEgc2V0IGNyZWF0ZWQgaGVyZSwgYGRhdC5tZWFuLmNzdmAsIGlzIHVzZWQgaW4gY2FsY3VsYXRpbmcgZWZmZWN0IHNpemVzIGZvciAgYW5hbHlzZXMgaW52ZXN0aWdhdGluZyBbcGhlbm90eXBpYyBtZWFuXSgjbWV0YS1hbmFseXNpcy1mb3ItcGhlbm90eXBpYy1tZWFuKSBhbmQgW25vdmVsdHkgaW4gcGhlbm90eXBpYyBtZWFuc10oI25vdmVsLXBoZW5vdHlwZS1leHByZXNzaW9uKS4NCg0KDQojIyBBbGxpZ24gcGFyZW50YWwgc3BlY2llcyBhY2NvcmRpbmcgdG8gcGhlbm90eXBpYyB2YXJpYXRpb24gKENWKQ0KDQpUbyBpbnZlc3RpZ2F0ZSBwYXRlcm5hbCBlZmZlY3QgaW4gaHlicmlkcyB1c2luZyBkaWZmZXJlbmNlIGluIGNvZWZmaWNpZW50IG9mIHZhcmlhdGlvbiAoQ1YpIGJldHdlZW4gcmVjaXByb2NhbCBjcm9zcywgaXQncyBiZXR0ZXIgdG8gYWxsaWduIHNwZWNpZXMgd2l0aCBsYXJnZXIgQ1YgKDxpPnNwTEw8c3ViPlY8L3N1Yj48L2k+KSBhbmQgc21hbGxlciBDViAoPGk+c3BTUzxzdWI+Vjwvc3ViPjwvaT4pIGluIGVhY2ggdHJhaXRzLiBOYW1lIG9mIGh5YnJpZHMgd2lsbCBiZSBjaGFuZ2VkIGFjY29yZGluZyB0byBjaGFuZ2UgaW4gbmFtZXMgb2YgcGFyZW50YWwgc3BlY2llcyAoPGk+aHlicmlkTFM8c3ViPlY8L3N1Yj48L2k+ICYgPGk+aHlicmlkU0w8c3ViPlY8L3N1Yj48L2k+KS4gIA0KDQpgYGB7cn0NCg0KIysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysjDQojIHNwMSA+PSBzcDIgaW4gcGhlbm90eXBpYyB2YXJpYXRpb24gKENWKQ0KIysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysjDQojIGV4dHJhY3QNCnNwMXNwMi52YXIgPC0gb3JpZ2luYWwuZGF0ICU+JQ0KICBmaWx0ZXIoU0Quc3AxL01uLnNwMSA+PSBTRC5zcDIvTW4uc3AyKSAjIGZpbHRlcmluZyBhY2NvcmRpbmcgdG8gQ1Ygb2YgcGFyZW50YWxzDQojIGNoYW5nZSBjb2x1bW4gbmFtZSBmcm9tIHNwMSBvciBzcDIgLT4gc3BMIG9yIHNwUw0KbmFtZXMoc3Axc3AyLnZhcikgPC0gZ3N1YigiMSIsICJMIiwgbmFtZXMoc3Axc3AyLnZhcikpDQpuYW1lcyhzcDFzcDIudmFyKSA8LSBnc3ViKCIyIiwgIlMiLCBuYW1lcyhzcDFzcDIudmFyKSkNCg0KIysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysjDQojIHNwMSA8IHNwMiBpbiBwaGVub3R5cGljIHZhcmlhdGlvbiAoQ1YpDQojKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyMNCiMgZXh0cmFjdA0Kc3Ayc3AxLnZhciA8LSBvcmlnaW5hbC5kYXQgJT4lDQogIGZpbHRlcihTRC5zcDEvTW4uc3AxIDwgU0Quc3AyL01uLnNwMikNCiMgY2hhbmdlIGNvbHVtbiBuYW1lIGZyb20gc3AxIG9yIHNwMiAtPiBzcFMgb3Igc3BMDQpuYW1lcyhzcDJzcDEudmFyKSA8LSBnc3ViKCIxIiwgIlMiLCBuYW1lcyhzcDJzcDEudmFyKSkNCm5hbWVzKHNwMnNwMS52YXIpIDwtIGdzdWIoIjIiLCAiTCIsIG5hbWVzKHNwMnNwMS52YXIpKQ0KDQojKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyMNCiMgY29tYmluZSBkYXRhc2V0ICYgc29ydCBieSBFUy5JRCANCiMrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrIw0KYmluZF9yb3dzKHNwMXNwMi52YXIsIHNwMnNwMS52YXIpICU+JQ0KICBhcnJhbmdlKEVTLklEKSAlPiUNCiAgd3JpdGUuY3N2KCIuLi9kYXRhL2RhdC5DVi5jc3YiLCBxdW90ZT1GLHJvdy5uYW1lcyA9IEYpDQoNCmBgYA0KRGF0YSBzZXQgY3JlYXRlZCBoZXJlLCBgZGF0LkNWLmNzdmAsIGlzIHVzZWQgaW4gY2FsY3VsYXRpbmcgZWZmZWN0IHNpemVzIGZvciBhbmFseXNlcyBpbnZlc3RpZ2F0aW5nIFtwaGVub3R5cGljIHZhcmlhdGlvbl0oI21ldGEtYW5hbHlzaXMtZm9yLXBoZW5vdHlwaWMtdmFyaWF0aW9uKSBhbmQgW25vdmVsdHkgaW4gcGhlbm90eXBpYyB2YXJpYWJpbGl0aWVzXSgjbm92ZWwtdmFyaWFiaWxpdHktZXhwcmVzc2lvbikuDQoNCg0KIyMgU2ltdWx0YW5lb3VzbHkganVkZ2Ugbm92ZWwgcGhlbm90eXBlIGFuZCB2YXJpYWJpbGl0eSBleHByZXNzaW9uDQpXZSBjYXRlZ29yaXNlZCBwaGVub3R5cGljIG5vdmVsdHkgKG5vdmVsIG9yIG5vbi1ub3ZlbCkgYW5kIHJlbGF0aXZlIHBoZW5vdHlwaWMgdmFyaWFiaWxpdHkgKENWKSBjb21wYXJlZCB0byBwYXJlbnRzIChzbWFsbGVyLCBpbnRlcm1lZGlhdGUsIGxhcmdlcikgYXQgZWFjaCB0cmFpdC4gDQoNCmBgYHtyfQ0KDQpiaW5kX3Jvd3MoDQogICMgQXNzZXNzIG5vdmVsIHBoZW5vdHlwZSAmIHZhcmlhYmlsaXR5IGV4cHJlc3Npb24gaW4gaHliMTINCiAgb3JpZ2luYWwuZGF0ICU+JQ0KICAgIGRyb3BfbmEoTW4uaHliMTIsIFNELmh5YjEyKSAlPiUNCiAgICBtdXRhdGUoDQogICAgICBjcm9zcyA9ICIxeDIiLA0KICAgICAgIyBSZWxhdGl2ZSB0cmFpdCBzaXplDQogICAgICByZWxhdGl2ZS5tZWFuID0gaWZlbHNlKA0KICAgICAgICAjIEV4Y2VlZGluZyB1cHBlciByYW5nZQ0KICAgICAgICBNbi5oeWIxMiA+IE1uLnNwMSAmIE1uLmh5YjEyID4gTW4uc3AyLA0KICAgICAgICAiTGFyZ2VyIiwNCiAgICAgICAgaWZlbHNlKA0KICAgICAgICAgICMgRXhjZWVkaW5nIGxvd2VyIHJhbmdlDQogICAgICAgICAgTW4uaHliMTIgPCBNbi5zcDEgJiBNbi5oeWIxMiA8IE1uLnNwMiwNCiAgICAgICAgICAiU21hbGxlciIsDQogICAgICAgICAgIkludGVybWVkaWF0ZSINCiAgICAgICAgKQ0KICAgICAgKSwNCiAgICAgICMgUmVsYXRpdmUgdmFyaWFiaWxpdHkgc2l6ZQ0KICAgICAgcmVsYXRpdmUudmFyID0gaWZlbHNlKA0KICAgICAgICAjIEV4Y2VlZGluZyB1cHBlciByYW5nZTogMQ0KICAgICAgICBTRC5oeWIxMi9Nbi5oeWIxMiA+IFNELnNwMS9Nbi5zcDEgJiANCiAgICAgICAgICBTRC5oeWIxMi9Nbi5oeWIxMiA+IFNELnNwMi9Nbi5zcDIsDQogICAgICAgICJMYXJnZXIiLA0KICAgICAgICBpZmVsc2UoDQogICAgICAgICAgIyBFeGNlZWRpbmcgbG93ZXIgcmFuZ2U6ICJTbWFsbGVyIg0KICAgICAgICAgIFNELmh5YjEyL01uLmh5YjEyIDwgU0Quc3AxL01uLnNwMSAmIA0KICAgICAgICAgICAgU0QuaHliMTIvTW4uaHliMTIgPCBTRC5zcDIvTW4uc3AyLA0KICAgICAgICAgICJTbWFsbGVyIiwNCiAgICAgICAgICAiSW50ZXJtZWRpYXRlIg0KICAgICAgICApDQogICAgICApICAgIA0KICAgICksDQogICMgQXNzZXNzIG5vdmVsIHBoZW5vdHlwZSAmIHZhcmlhYmlsaXR5IGV4cHJlc3Npb24gaW4gaHliMTINCiAgb3JpZ2luYWwuZGF0ICU+JQ0KICAgIGRyb3BfbmEoTW4uaHliMjEsIFNELmh5YjIxKSAlPiUNCiAgICBtdXRhdGUoDQogICAgICBjcm9zcyA9ICIyeDEiLA0KICAgICAgIyBSZWxhdGl2ZSB0cmFpdCBzaXplDQogICAgICByZWxhdGl2ZS5tZWFuID0gaWZlbHNlKA0KICAgICAgICAjIEV4Y2VlZGluZyB1cHBlciByYW5nZTogMQ0KICAgICAgICBNbi5oeWIyMSA+IE1uLnNwMSAmIE1uLmh5YjIxID4gTW4uc3AyLA0KICAgICAgICAiTGFyZ2VyIiwNCiAgICAgICAgaWZlbHNlKA0KICAgICAgICAgICMgRXhjZWVkaW5nIGxvd2VyIHJhbmdlOiAiU21hbGxlciINCiAgICAgICAgICBNbi5oeWIyMSA8IE1uLnNwMSAmIE1uLmh5YjIxIDwgTW4uc3AyLA0KICAgICAgICAgICJTbWFsbGVyIiwNCiAgICAgICAgICAiSW50ZXJtZWRpYXRlIg0KICAgICAgICApIA0KICAgICAgKSAsDQogICAgICAjIFJlbGF0aXZlIHZhcmlhYmlsaXR5IHNpemUNCiAgICAgIHJlbGF0aXZlLnZhciA9IGlmZWxzZSgNCiAgICAgICAgIyBFeGNlZWRpbmcgdXBwZXIgcmFuZ2U6IDENCiAgICAgICAgU0QuaHliMjEvTW4uaHliMjEgPiBTRC5zcDEvTW4uc3AxICYgDQogICAgICAgICAgU0QuaHliMjEvTW4uaHliMjEgPiBTRC5zcDIvTW4uc3AyLA0KICAgICAgICAiTGFyZ2VyIiwNCiAgICAgICAgaWZlbHNlKA0KICAgICAgICAgICMgRXhjZWVkaW5nIGxvd2VyIHJhbmdlOiAiU21hbGxlciINCiAgICAgICAgICBTRC5oeWIyMS9Nbi5oeWIyMSA8IFNELnNwMS9Nbi5zcDEgJiANCiAgICAgICAgICAgIFNELmh5YjIxL01uLmh5YjIxIDwgU0Quc3AyL01uLnNwMiwNCiAgICAgICAgICAiU21hbGxlciIsDQogICAgICAgICAgIkludGVybWVkaWF0ZSINCiAgICAgICAgKQ0KICAgICAgKSAgICANCiAgICApIA0KICApICU+JQ0KICBtdXRhdGUobWVhbi5ub3ZlbHR5ID0gaWZlbHNlKHJlbGF0aXZlLm1lYW4gPT0gIkludGVybWVkaWF0ZSIsICJOb25ub3ZlbCIsICJOb3ZlbCIpKSAlPiUNCiAgd3JpdGUuY3N2KCIuLi9kYXRhL2RhdC5ub3ZlbHR5LmNzdiIsIHF1b3RlPUYscm93Lm5hbWVzID0gRikNCg0KYGBgDQpEYXRhIHNldCBjcmVhdGVkIGhlcmUsIGBkYXQubm92ZWx0eS5jc3ZgLCBpcyB1c2VkIGluIGludmVzdGlnYXRpbmcgW3BoZW5vdHlwaWMgdmFyaWFiaWxpdHkgb2Ygbm92ZWwgcGhlbm90eXBlXSgjcGhlbm90eXBpYy12YXJpYWJpbGl0eS1vZi1ub3ZlbC1waGVub3R5cGUpLg0KDQoNCg0KPGRpdiBzdHlsZT0ibWFyZ2luLWJvdHRvbToxODBweDsiPg0KPC9kaXY+DQojIE1ldGEtYW5hbHlzaXMgZm9yIHBoZW5vdHlwaWMgbWVhbg0KDQpXZSBjcmVhdGVkIGRhdGEgc3Vic2V0IGFjY29yZGluZyB0byB0YXhvbiAoYWxsIHRheG9uIG9yIGluc2VjdCBvbmx5KSBhbmQgbm92ZWx0eSBpbiBwaGVub3R5cGljIG1lYW5zIChhbGwgdHJhaXRzIG9yIG5vbi1ub3ZlbCB0cmFpdHMgLSB0cmFpdCBzaXplIG9mIGh5YnJpZHMgZG9lcyBub3QgZXhjZWVkIHNpemUgcmFuZ2Ugb2YgcGFyZW50cykuIFdlIGNvbmR1Y3QgaWRlbnRpY2FsIGFuYWx5c2VzIGZvciBmdWxsIGRhdGEgYW5kIGRhdGEgc3Vic2V0cywgYW5kIGNoZWNrZWQgcm9idXN0bmVzcyBvZiBvdXIgcmVzdWx0cy4NCg0KIyMgQ2FsY3VsYXRpbmcgZWZmZWN0IHNpemVzDQoNClRvIHF1YW50aWZ5IHBoZW5vdHlwaWMgZGlmZmVyZW5jZSBmcm9tIDxpPnNwU1M8c3ViPk08L3N1Yj48L2k+IHRvIHRoZSBvdGhlciBjcm9zc2VzLCB3ZSBjYWxjdWxhdGVkIGxvZyByZXNwb25zZSByYXRpbyAobG5SUikgZnJvbSBwaGVub3R5cGljIG1lYW4gb2YgPGk+c3BTUzxzdWI+TTwvc3ViPjwvaT4gdG8gdGhvc2Ugb2YgdGhlIG90aGVyIGNyb3NzZXMgKDxpPmh5YkxTPHN1Yj5NPC9zdWI+PC9pPiwgPGk+aHliU0w8c3ViPk08L3N1Yj48L2k+IGFuZCA8aT5zcExMPHN1Yj5NPC9zdWI+PC9pPikuPGJyPg0KRWZmZWNjdCBzaXplIHdhcyBjYWxjdWxhdGVkIGJ5IHVzaW5nIGBlc2NhbGNgIGZ1bmN0aW9uIGluIGBtZXRhZm9yYCBwYWNrYWdlIA0KDQpgYGB7cn0NCg0KIyBsb2FkIHBoZW5vdHlwaWMgZGF0YQ0KZGF0IDwtIHJlYWQuY3N2KCIuLi9kYXRhL2RhdC5tZWFuLmNzdiIsIGhlYWQgPSBUUlVFKQ0KDQojIE9yZGVyIGJ5IHRheG9uDQpkYXQkdGF4YSA8LSBvcmRlcmVkKA0KICBkYXQkdGF4YSwNCiAgbGV2ZWxzID0gYygiTmV1cm9wdGVyYSIsICJDb2xlb3B0ZXJhIiwgIkRpcHRlcmEiLCAiTGVwaWRvcHRlcmEiLCAiT3J0aG9wdGVyYSIsICJBdmVzIiwgIlJvZGVudGlhIiwgIkFudXJhIiwgIkNpY2hsaWZvcm1lcyIpDQogICkNCg0KIyMgRGlmZmVyZW5jZSBiZXR3ZWVuIGh5YnJpZHMgYW5kIHNtYWxsZXIgc3BlY2llcyAoc3BTKSAjIyMNCm1lYW4uZGlmIDwtIGZvcmVhY2goDQogIGNyID0gYygiaHliTFMiLCAiaHliU0wiLCAic3BMIiksIA0KICAuY29tYmluZSA9IGByYmluZGANCiAgKSAlZG8lIHsNCiAgICAjIyBsblJSICMjIw0KICAgIGVzY2FsYygNCiAgICAgIG1lYXN1cmUgPSAiUk9NIiwNCiAgICAgICMgTiBvZiBoeWJyaWRzDQogICAgICBuMWkgPSBkYXRbLCBwYXN0ZSgiTiIsIGNyLCBzZXAgPSAiLiIpXSwNCiAgICAgICMgTiBvZiBwYXJlbnRhbHMNCiAgICAgIG4yaSA9IGRhdFssICJOLnNwUyJdLA0KICAgICAgIyBNZWFuIG9mIGh5YnJpZHMNCiAgICAgIG0xaSA9IGRhdFssIHBhc3RlKCJNbiIsIGNyLCBzZXAgPSAiLiIpXSwNCiAgICAgICMgTWVhbiBvZiBwYXJlbnRhbHMNCiAgICAgIG0yaSA9IGRhdFssICJNbi5zcFMiXSwNCiAgICAgICMgU0Qgb2YgaHlicmlkcw0KICAgICAgc2QxaSA9IGRhdFssIHBhc3RlKCJTRCIsIGNyLCBzZXAgPSAiLiIpXSwNCiAgICAgICMgU0Qgb2YgcGFyZW50YWxzDQogICAgICBzZDJpID0gZGF0WywgIlNELnNwUyJdLA0KICAgICAgZGF0YSA9IGRhdA0KICAgICAgKSAlPiUNCiAgICAgIHJlbmFtZShsblJSLmVzID0geWksIGxuUlIuc3YgPSB2aSkgJT4lDQogICAgIyBpbmRpY2F0ZSB0eXBlIG9mIGh5YnJpZA0KICAgIG11dGF0ZShjcm9zcyA9IGNyKQ0KICAgIH0gJT4lIA0KICBkcm9wX25hKGxuUlIuc3YpICU+JQ0KICBhcnJhbmdlKEVTLklEKSAlPiUNCiAgbGVmdF9qb2luKC4sIGRhdCkgDQogIA0KIyBEYXRhc2V0IGFibGUgdG8gY29tcGFyZSByZWNpcHJvY2FsIGNyb3NzZXMNCndyaXRlLmNzdigNCiAgbWVhbi5kaWYgJT4lDQogICAgZmlsdGVyKFJlY2lwcm9jYWwgPT0gIlZpYWJsZSIpLCANCiAgIi4uL2RhdGEvbWVhbi5FUy5nZW5lcmFsLmNzdiIsIHJvdy5uYW1lcyA9IEYNCiAgKQ0KDQpgYGANCg0KDQojIyBGdW5uZWwgcGxvdHMNCg0KYGBge3J9DQoNCnJlcyA8LSBybWEoDQogIHlpID0gbG5SUi5lcywgdmkgPSBsblJSLnN2LCANCiAgZGF0YSA9IG1lYW4uZGlmLCBtZXRob2Q9IkZFIg0KICApDQoNCiMjIHNldCB1cCAyeDIgYXJyYXkgZm9yIHBsb3R0aW5nDQpwYXIobWZyb3c9YygyLDIpKQ0KIA0KIyMgZHJhdyBmdW5uZWwgcGxvdHMNCmZ1bm5lbChyZXMsIG1haW49IlN0YW5kYXJkIEVycm9yIiwgeGxpbSA9IGMoLTIsIDQpKQ0KZnVubmVsKHJlcywgeWF4aXM9InZpIiwgbWFpbj0iU2FtcGxpbmcgVmFyaWFuY2UiLCB4bGltID0gYygtMiwgNCkpDQpmdW5uZWwocmVzLCB5YXhpcz0ic2VpbnYiLCBtYWluPSJJbnZlcnNlIFN0YW5kYXJkIEVycm9yIiwgeGxpbSA9IGMoLTIsIDQpKQ0KZnVubmVsKHJlcywgeWF4aXM9InZpbnYiLCBtYWluPSJJbnZlcnNlIFNhbXBsaW5nIFZhcmlhbmNlIiwgeGxpbSA9IGMoLTIsIDQpKQ0KDQpgYGANCg0KIyMgQ2hlY2sgZGF0YQ0KQ2hlY2tlZCBlZmZlY3Qgc2l6ZXMgd2l0aCBleHRyZW1lbHkgaGlnaC9sb3cgc3RhbmRhcmQgZXJyb3IgKFNFID4gMS4yIHwgMS9TRSA+IDE0MCkgYW5kIGNvbmZpcm1lZCB0aGF0IHRob3NlIGRhdGEgd2VyZSBjb3JyZWN0bHkgaW1wb3J0ZWQuIA0KDQpgYGB7ciwgcmVzdWx0cz0nYXNpcyd9DQoNCm91dGxpZXJzIDwtIG1lYW4uZGlmICU+JQ0KICAjIHZpIChzYW1wbGluZyB2YXJpYW5jZSkgDQogIG11dGF0ZShTRSA9IHNxcnQobG5SUi5zdikpICU+JQ0KICBhcnJhbmdlKGRlc2MoU0UpKSAlPiUNCiAgZmlsdGVyKFNFID4gMS4yIHwgMS9TRSA+IDE0MCkgJT4lDQogIHNlbGVjdChFUy5JRCwgU3R1ZHkubmFtZSwgU0UsIGNyb3NzLCBSZWNpcHJvY2FsLCB0cmFpdCwgQ3Jvc3MuSUQpICU+JQ0KICBtdXRhdGVfaWYoaXMubnVtZXJpYywgcm91bmQsIDMpDQoNCm91dGxpZXJzICU+JQ0KICBrYWJsZSgiaHRtbCIsIGRpZ2l0cyA9IDMsIGNhcHRpb24gPSAiRWZmZWN0IHNpemVzIHdpdGggZXh0cmVtZWx5IGhpZ2gvbG93IHN0YW5kYXJkIGVycm9yIChTRSA+IDEuMiB8IDEvU0UgPiAxNDApIikgJT4lIA0KICBrYWJsZV9zdHlsaW5nKCJzdHJpcGVkIiwgcG9zaXRpb24gPSAibGVmdCIpICU+JQ0KICBzY3JvbGxfYm94KHdpZHRoID0gIjEwMCUiLCBoZWlnaHQgPSAiNTAwcHgiKQ0KDQpgYGANCg0KQmVjYXVzZSB0aG9zZSBvdXRsaWVycyBkaWQgbm90IGFmZmVjdCBtZXRhLWFuYWx5dGljIG1vZGVsIGNvbnZlcmdlbmNlLCB3ZSBkaWQgbm90IGV4Y2x1ZGUgdGhvc2UgZGF0YS4NCjxkaXYgc3R5bGU9Im1hcmdpbi1ib3R0b206NzBweDsiPg0KPC9kaXY+DQoNCiMjIEp1ZGdpbmcgbm92ZWx0eSBpbiBwaGVub3R5cGljIG1lYW5zIA0KDQpgYGB7cn0NCg0KIyBsb2FkIHNwTFMgZmlsZXMNCmRhdCA8LSByZWFkLmNzdigiLi4vZGF0YS9kYXQubWVhbi5jc3YiLCBoZWFkID0gVFJVRSkNCg0KIysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysjDQojIERpZmZlcmVuY2UgYmV0d2VlbiBsYXJnZXIgc3BlY2llcyAoc3BMKSBhbmQgaHlicmlkcyANCiMrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrIw0KDQpmb3IgKGkgaW4gYygic3BMIikpIHsgIyBpZGVudGlmeSB0eXBlIG9mIGh5YnJpZHMNCiAgZm9yIChjciBpbiBjKCJoeWJMUyIsICJoeWJTTCIpKSB7ICMgaWRlbnRpZnkgdHlwZSBvZiBwYXJlbnRhbHMNCiAgICBhc3NpZ24oDQogICAgICBwYXN0ZShjciwgaSwgc2VwID0gIl8iKSwNCiAgICAgICAgIyMgbG5SUiAjIyMNCiAgICAgICAgZXNjYWxjKA0KICAgICAgICAgIG1lYXN1cmUgPSAiUk9NIiwNCiAgICAgICAgICAjIE4gb2YgaHlicmlkcw0KICAgICAgICAgIG4xaSA9IGRhdFssIHBhc3RlKCJOIiwgaSwgc2VwID0gIi4iKV0sDQogICAgICAgICAgIyBOIG9mIHBhcmVudGFscw0KICAgICAgICAgIG4yaSA9IGRhdFssIHBhc3RlKCJOIiwgY3IsIHNlcCA9ICIuIildLA0KICAgICAgICAgICMgTWVhbiBvZiBoeWJyaWRzDQogICAgICAgICAgbTFpID0gZGF0WywgcGFzdGUoIk1uIiwgaSwgc2VwID0gIi4iKV0sDQogICAgICAgICAgIyBNZWFuIG9mIHBhcmVudGFscw0KICAgICAgICAgIG0yaSA9IGRhdFssIHBhc3RlKCJNbiIsIGNyLCBzZXAgPSAiLiIpXSwNCiAgICAgICAgICAjIFNEIG9mIGh5YnJpZHMNCiAgICAgICAgICBzZDFpID0gZGF0WywgcGFzdGUoIlNEIiwgaSwgc2VwID0gIi4iKV0sDQogICAgICAgICAgIyBTRCBvZiBwYXJlbnRhbHMNCiAgICAgICAgICBzZDJpID0gZGF0WywgcGFzdGUoIlNEIiwgY3IsIHNlcCA9ICIuIildLA0KICAgICAgICAgIGRhdGEgPSBkYXQNCiAgICAgICAgICApICU+JQ0KICAgICAgICByZW5hbWUobG5SUi5lcyA9IHlpLCBsblJSLnN2ID0gdmkpICU+JQ0KICAgICAgICBzZWxlY3QoRVMuSUQsIGNvbnRhaW5zKCJsblJSIikpICU+JQ0KICAgICAgICBtdXRhdGUoDQogICAgICAgICAgIyBkaXJlY3Rpb24gb2YgdHJhbnNncmVzc3ZlIHNlZ3JlZ2F0aW9uIC0gZ3JlYXRlciB0aGFuIHBhcmVudA0KICAgICAgICAgIGRpcmVjdGlvbiA9ICIrIiwNCiAgICAgICAgICAjIFNFIGZvciBsb2dpc3RpYyBkaXN0cmlidXRpb24sIGZvciB0aGUgd2VpZ2h0ZWQgYmlub21pYWwgcmVncmVzc2lvbg0KICAgICAgICAgICMgU0UgPSBwaS9zcXJ0KDMqKG5fZSArIG5fYykpDQogICAgICAgICAgU0UgPSBwaS9zcXJ0KDMqKA0KICAgICAgICAgICAgZGF0WywgcGFzdGUoIk4iLCBpLCBzZXAgPSAiLiIpXSArIGRhdFssIHBhc3RlKCJOIiwgY3IsIHNlcCA9ICIuIildDQogICAgICAgICAgKSkNCiAgICAgICAgKQ0KICAgICkNCiAgfQ0KfQ0KDQojKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyMNCiMgRGlmZmVyZW5jZSBiZXR3ZWVuIGh5YnJpZHMgYW5kIHNtYWxsZXIgc3BlY2llcyAoc3BTKQ0KIysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysjDQoNCmZvciAoaSBpbiBjKCJoeWJMUyIsICJoeWJTTCIpKSB7ICMgaWRlbnRpZnkgdHlwZSBvZiBoeWJyaWRzDQogIGZvciAoY3IgaW4gYygic3BTIikpIHsgIyBpZGVudGlmeSB0eXBlIG9mIHBhcmVudGFscw0KICAgIGFzc2lnbigNCiAgICAgIHBhc3RlKGksIGNyLCBzZXAgPSAiXyIpLA0KICAgICAgICAjIyBsblJSICMjIw0KICAgICAgICBlc2NhbGMoDQogICAgICAgICAgbWVhc3VyZSA9ICJST00iLA0KICAgICAgICAgICMgTiBvZiBoeWJyaWRzDQogICAgICAgICAgbjFpID0gZGF0WywgcGFzdGUoIk4iLCBpLCBzZXAgPSAiLiIpXSwNCiAgICAgICAgICAjIE4gb2YgcGFyZW50YWxzDQogICAgICAgICAgbjJpID0gZGF0WywgcGFzdGUoIk4iLCBjciwgc2VwID0gIi4iKV0sDQogICAgICAgICAgIyBNZWFuIG9mIGh5YnJpZHMNCiAgICAgICAgICBtMWkgPSBkYXRbLCBwYXN0ZSgiTW4iLCBpLCBzZXAgPSAiLiIpXSwNCiAgICAgICAgICAjIE1lYW4gb2YgcGFyZW50YWxzDQogICAgICAgICAgbTJpID0gZGF0WywgcGFzdGUoIk1uIiwgY3IsIHNlcCA9ICIuIildLA0KICAgICAgICAgICMgU0Qgb2YgaHlicmlkcw0KICAgICAgICAgIHNkMWkgPSBkYXRbLCBwYXN0ZSgiU0QiLCBpLCBzZXAgPSAiLiIpXSwNCiAgICAgICAgICAjIFNEIG9mIHBhcmVudGFscw0KICAgICAgICAgIHNkMmkgPSBkYXRbLCBwYXN0ZSgiU0QiLCBjciwgc2VwID0gIi4iKV0sDQogICAgICAgICAgZGF0YSA9IGRhdA0KICAgICAgICAgICkgJT4lDQogICAgICAgICAgcmVuYW1lKGxuUlIuZXMgPSB5aSwgbG5SUi5zdiA9IHZpKSAlPiUNCiAgICAgICAgc2VsZWN0KEVTLklELCBjb250YWlucygibG5SUiIpKSAlPiUNCiAgICAgICAgbXV0YXRlKA0KICAgICAgICAgICMgZGlyZWN0aW9uIG9mIHRyYW5zZ3Jlc3N2ZSBzZWdyZWdhdGlvbiAtIHNtYWxsZXIgdGhhbiBwYXJlbnQNCiAgICAgICAgICBkaXJlY3Rpb24gPSAiLSIsDQogICAgICAgICAgIyBTRSBmb3IgbG9naXN0aWMgZGlzdHJpYnV0aW9uLCBmb3IgdGhlIHdlaWdodGVkIGJpbm9taWFsIHJlZ3Jlc3Npb24NCiAgICAgICAgICAjIFNFID0gcGkvc3FydCgzKihuX2UgKyBuX2MpKQ0KICAgICAgICAgIFNFID0gcGkvc3FydCgzKigNCiAgICAgICAgICAgIGRhdFssIHBhc3RlKCJOIiwgaSwgc2VwID0gIi4iKV0gKyBkYXRbLCBwYXN0ZSgiTiIsIGNyLCBzZXAgPSAiLiIpXQ0KICAgICAgICAgICkpDQogICAgICAgICkNCiAgICApDQogIH0NCn0NCg0KIysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysjDQojIERhdGEgb3V0cHV0DQojKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyMNCg0KYmluZF9yb3dzKA0KICAjIyBEaWZmZXJlbmNlIHdpdGggbW90aGVyIHNwZWNpZXMgIyMjDQogIGJpbmRfcm93cyhoeWJMU19zcEwsIGh5YlNMX3NwUykgJT4lDQogICAgbXV0YXRlKHBhcmVudGFsID0gIk1vdGhlciIpLA0KICAjIyBEaWZmZXJlbmNlIHdpdGggZmF0aGVyIHNwZWNpZXMgIyMjDQogIGJpbmRfcm93cyhoeWJMU19zcFMsIGh5YlNMX3NwTCkgJT4lDQogICAgbXV0YXRlKHBhcmVudGFsID0gIkZhdGhlciIpDQogICkgJT4lDQogIGRyb3BfbmEobG5SUi5zdikgJT4lDQogIGxlZnRfam9pbiguLCBkYXQpICU+JQ0KICAjIEFzc2lnbiBub3ZlbCBwaGVub3R5cGUgdG8gMSwgbm9uLW5vdmVsIHBoZW5vdHlwZSB0byAwIGZvciBlYWNoIGVmZmVjdCBzaXplDQogIG11dGF0ZShOb3ZlbHR5ID0gaWZlbHNlKGxuUlIuZXMgPCAwLCAxLCAwKSkgJT4lDQogICMjIEpvaW4gd2l0aCBtZXRhZGF0YSAjIyMNCiAgbGVmdF9qb2luKA0KICAgIC4sIHJlYWQueGxzeCgiLi4vZGF0YS9vcmlnaW5hbC5kYXRhLnhsc3giLCBzaGVldCA9ICJTcGVjaWVzLmxldmVsLm1vZGVyYXRvcnMiKQ0KICAgICkgJT4lDQogIG11dGF0ZV9hdCh2YXJzKGNvbnRhaW5zKCJkaXZlcmdlbmNlIikpLCBhcy5udW1lcmljKSAlPiUNCiAgbXV0YXRlX2F0KHZhcnMoY29udGFpbnMoImRpdmVyZ2VuY2UiKSksIHNjYWxlKSAlPiUNCiAgYXMuZGF0YS5mcmFtZSAlPiUNCiAgc2VsZWN0KC10cmFpdCkgJT4lDQogIG11dGF0ZV9hdCgidGF4YSIsIGFzLmZhY3RvcikgJT4lDQogIHdpdGhpbihsZXZlbHMoTm92ZWx0eSkgPC0gYygiTm8iLCAiTm92ZWwgcGhlbm90eXBpYyBtZWFucyIpKSAlPiUNCiAgd2l0aGluKA0KICAgIHRheGEgPC0gb3JkZXJlZCgNCiAgICAgIHRheGEsDQogICAgICBsZXZlbHMgPSBjKCJOZXVyb3B0ZXJhIiwgIkNvbGVvcHRlcmEiLCAiRGlwdGVyYSIsICJMZXBpZG9wdGVyYSIsICJPcnRob3B0ZXJhIiwgIkF2ZXMiLCAiUm9kZW50aWEiLCAiQW51cmEiLCAiQ2ljaGxpZm9ybWVzIikNCiAgICAgICkNCiAgICApICU+JQ0KICAjIFJlbW92ZSByb3dzIHdpdGhvdXQgYW55IG1ldGFkYXRhDQogIGRyb3BfbmEoSGV0ZXJvLnNleCwgUGhlbm8uZGl2ZXJnZW5jZSwgdHJhaXQudHlwZSwgR2VuZXQuZGl2ZXJnZW5jZSkgJT4lDQogICMgSW5zZWN0IG9yIG5vDQogIG11dGF0ZSgNCiAgICBpbnNlY3QgPSBpZmVsc2UodGF4YSAlaW4lIGMoIkF2ZXMiLCAiUm9kZW50aWEiLCAiQW51cmEiLCAiQ2ljaGxpZm9ybWVzIiksICJubyIsICJpbnNlY3QiKSwNCiAgKSAlPiUNCiAgd3JpdGUuY3N2KCIuLi9kYXRhL21lYW4uRVMuTm92ZWx0eS5jc3YiLCByb3cubmFtZXMgPSBGKQ0KDQpgYGANCg0KDQojIyBSZWxvYWQgZGF0YSAmIFByZXBhcmUgcGh5bG9nZW5ldGljIHRyZWUNCg0KYGBge3IsIGZpZy5oZWlnaHQgPSA2LjUsIGZpZy5jYXAgPSAiRmlndXJlIFMxLiBQaHlsb2dlbmV0aWMgdHJlZSB1c2VkIGluIG1ldGEtYW5hbHlzaXMgZm9yIHBoZW5vdHlwaWMgbWVhbiwgd2hpY2ggd2FzIGJhc2VkIG9uIHRyZWUgb2YgdGhlIHBhcmVudGFsIHNwZWNpZXMgd2l0aCBsYXJnZXIgcGhlbm90eXBpYyBtZWFuIn0NCg0KIyBMb2FkIGVmZmVjdCBzaXplcw0KbWVhbi5kaWYgPC0gcmVhZC5jc3YoIi4uL2RhdGEvbWVhbi5FUy5nZW5lcmFsLmNzdiIsIGhlYWQgPSBUUlVFKSAlPiUNCiAgIyBpbmRpY2F0ZSBkYXRhc2V0IGluY2x1ZGluZyBub3ZlbCBwaGVub3R5cGUNCiAgbXV0YXRlKGRhdGEudHlwZSA9ICJBbGx0cmFpdHMiKQ0KDQojIEFsbCB0cmFpdCBvYnNlcnZhdGlvbiBpcnJlc3BlY3RpdmUgb2YgcGhlbm90eXBpYyBub3ZlbHR5DQpBbGwgPC0gcmVhZC5jc3YoIi4uL2RhdGEvbWVhbi5FUy5Ob3ZlbHR5LmNzdiIsIGhlYWQgPSBUUlVFKSAlPiUNCiAgZmlsdGVyKGxuUlIuZXMgPCAwKSAlPiUNCiAgZGlzdGluY3QoRVMuSUQpDQoNCiMgVHJhaXQgb2JzZXJ2YXRpb24gb2Ygbm9uLW5vdmVsIHBoZW5vdHlwZXMNCk5vbm92ZWwgPC0gcmVhZC5jc3YoIi4uL2RhdGEvbWVhbi5FUy5nZW5lcmFsLmNzdiIsIGhlYWQgPSBUUlVFKSAlPiUNCiAgZmlsdGVyKCEoRVMuSUQgJWluJSBBbGwkRVMuSUQpKSAlPiUNCiAgIyBpbmRpY2F0ZSBkYXRhc2V0IHdpdGhvdXQgbm92ZWwgcGhlbm90eXBlDQogIG11dGF0ZShkYXRhLnR5cGUgPSAiTm9ubm92ZWx0cmFpdHMiKQ0KDQojIGNvbWJpbmUgZGF0YXNldCB3aXRoL3dpdGhvdXQgbm92ZWwgcGhlbm90eXBlDQpOb3ZlbC5Ob25ub3ZlbCA8LSBiaW5kX3Jvd3MobWVhbi5kaWYsIE5vbm92ZWwpICU+JQ0KICBtdXRhdGUobWV0YXVuaXQgPSAgc3RyX2MoZGF0YS50eXBlLCBjcm9zcywgc2VwID0gIl8iKSklPiUNCiAgIyBVc2Ugb2JzZXJ2YXRpb25zIHdpdGggYm90aCByZWNpcHJvY2FsIGNyb3NzZXMNCiAgZHJvcF9uYShjb250YWlucygiTW4iKSwgY29udGFpbnMoIlNEIikpICU+JQ0KICAjIEluc2VjdCBvciBubw0KICBtdXRhdGUoDQogICAgaW5zZWN0ID0gaWZlbHNlKHRheGEgJWluJSBjKCJDaWNobGlmb3JtZXMiLCAiQW51cmEiLCAiQXZlcyIsICJSb2RlbnRpYSIpLCAibm8iLCAiaW5zZWN0IiksDQogICkNCg0KDQojKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysjDQojIFBoeWxvZ2VueQ0KIysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrIw0KDQojICMgbWF0Y2hpbmcgbmFtZXMgZnJvbSBvcGVuIHRyZWUgdGF4b25vbXkNCiMgdGF4YSA8LSB0bnJzX21hdGNoX25hbWVzKA0KIyAgIG5hbWVzID0gbGV2ZWxzKG1lYW4uZGlmJHNwTC5uYW1lKSAlPiUNCiMgICAgIHN0cl9yZXBsYWNlX2FsbCgiXyIsICIgIiksIA0KIyAgIGNvbnRleHRfbmFtZSA9ICJBbmltYWxzIg0KIyAgICkNCiMgDQojICMgd2hpY2ggbmFtZXMgcmV0dXJuIG1vcmUgdGhhbiAxIG1hdGNoPw0KIyBpbnNwZWN0KHRheGEsIG90dF9pZCA9IHRheGEkb3R0X2lkW3RheGEkbnVtYmVyX21hdGNoZXMgIT0gMV0pDQojIA0KIyAjIGZpeGluZyBuYW1lcyB3aXRoIG1vcmUgdGhhbiAxIG1hdGNoDQojIHRheGFbdGF4YSRudW1iZXJfbWF0Y2hlcyAhPSAxLCBdIDwtIA0KIyAgIGluc3BlY3QodGF4YSwgb3R0X2lkID0gdGF4YSRvdHRfaWRbdGF4YSRudW1iZXJfbWF0Y2hlcyAhPSAxXSlbMSwgXQ0KIyANCiMgdHJlZSA8LSB0b2xfaW5kdWNlZF9zdWJ0cmVlKG90dF9pZHMgPSB0YXhhJG90dF9pZCkNCiMgdHJlZSR0aXAubGFiZWwgJTw+JQ0KIyAgIHN0cmlwX290dF9pZHMocmVtb3ZlX3VuZGVyc2NvcmVzPVRSVUUpDQojIA0KIyBwcmludCgiT3JpZ2luYWwgdHJlZSBmcm9tIE9UTCIpDQojIHBsb3QodHJlZSwgbm8ubWFyZ2luPVRSVUUpDQojIA0KIyAjIHJhbmRvbWx5IHNvbHZlIG5vbi1iaW5hcnkgcGh5bG9nZW55DQojIHNldC5zZWVkKDYpDQojIGJpbi50cmVlIDwtIG11bHRpMmRpKHRyZWUsIHJhbmRvbSA9IFQpIA0KIyBwcmludCgiUmFuZG9tbHkgc29sdmVkIHBoeWxvZ2VueSIpDQojIHBsb3QoYmluLnRyZWUpDQojIA0KIyAjIGNvcnJlbGF0aW9uIG1hdHJpeCB0byBmaXQgdG8gdGhlIG1vZGVsDQojIGJpbi50cmVlJHRpcC5sYWJlbCA8LSBiaW4udHJlZSR0aXAubGFiZWwgJT4lDQojICAgYXMuZmFjdG9yKCkgDQojIA0KIyBsZXZlbHMoYmluLnRyZWUkdGlwLmxhYmVsKSA8LSBsZXZlbHMobWVhbi5kaWYkc3BMLm5hbWUpICMgbWFraW5nIHN1cmUgbmFtZXMgbWF0Y2gNCiMgYmluLnRyZWUkdGlwLmxhYmVsIDwtIGFzLmNoYXJhY3RlcihiaW4udHJlZSR0aXAubGFiZWwpICMgY29udmVydGluZyBuYW1lcyBiYWNrIHRvIGNoYXJhY3Rlcg0KIyANCiMgd3JpdGUudHJlZShiaW4udHJlZSwgZmlsZT0gIi4uL2RhdGEvcGh5bG8ubWVhbi50cmUiKQ0KDQojIGNvbXB1dGUgYnJhbmNoIGxlbmd0aHMgb2YgdHJlZQ0KcGh5bG9fYnJhbmNoIDwtIHJlYWQudHJlZShmaWxlID0gIi4uL2RhdGEvcGh5bG8ubWVhbi50cmUiKSAlPiUNCiAgY29tcHV0ZS5icmxlbihiaW4udHJlZSwgbWV0aG9kID0gIkdyYWZlbiIsIHBvd2VyID0gMSkNCg0KIyBzYXZpbmcgcGh5bG9nZW5laWMgbWF0cml4DQpwaHlsb19jb3IgPC0gdmN2KHBoeWxvX2JyYW5jaCwgY29yID0gVCkNCg0KIyBOb3RlIG9uZSBvZiB0aGUgdGlwcyBpcyBjYWxsZWQgIkxhdGVzIGNhbGNhcmlmZXIgKGVzdGltYXRlZCkiDQpwaHlsb19icmFuY2gkbm9kZS5sYWJlbCA8LSBOVUxMDQoNCiMgUGxvdCB0cmVlDQpwbG90LnBoeWxvKHBoeWxvX2JyYW5jaCwgY2V4ID0gMC43KQ0KDQpgYGANCjxicj4NClBoeWxvZ2VuZXRpYyB0cmVlIGNyZWF0ZWQgYmFzZWQgb24gdGF4b25vbWljIHRyZWUgb24gW09wZW4gVHJlZSBvZiBMaWZlXShodHRwczovL3RyZWUub3BlbnRyZWVvZmxpZmUub3JnL29wZW50cmVlL2FyZ3VzL29wZW50cmVlMTIuM0BvdHQ5MzMwMikuIE5vbi1iaW5hcnkgdHJlZSB3YXMgcmFuZG9tbHkgc29sdmVkLiBXZSB1c2VkIHBhY2thZ2VzIGByb3RsYCwgYGFwZWAgYW5kIGBwaHl0b29sc2Agb24gUi4NCg0KPGRpdiBzdHlsZT0ibWFyZ2luLWJvdHRvbTo3MHB4OyI+DQo8L2Rpdj4NCg0KIyMgRG9taW5hbmNlIGluIHBoZW5vdHlwaWMgbWVhbnMNCkNvbXBhcmUgbWlkcGFyZW50IGFuZCBoeWJyaWRzIGJ5IGNvbXBhcmluZyBkaWZmZXJlbmNlIGZyb20gPGk+c3BTUzxzdWI+TTwvc3ViPjwvaT4gcGhlbm90eXBpYyBtZWFuIHRvIG1pZHBhcmVudC12YWx1ZSAkXGZyYWN7c3BMTF9NK3NwU1NfTX17Mn0kIGFuZCB0byBoeWJyaWRzJyBwaGVub3R5cGljIG1lYW4uICANCg0KKiBsblJSIG9mIG1pZHBhcmVudCB0byA8aT5zcFNTPHN1Yj5NPC9zdWI+PC9pPjogJFxsblxmcmFje3NwTExfTStzcFNTX019ezJzcFNTX019JCANCiogbG5SUiBvZiBoeWJyaWRzIHRvIDxpPnNwU1M8c3ViPk08L3N1Yj48L2k+OiAkXGxuXGZyYWN7aHlicmlkfXtzcFNTX019JCANCg0KQXMgdGhlIHZhcmlhbmNlIG9mICRcbG5cZnJhY3tzcExMX00rc3BTU19NfXsyc3BTU19NfSQsIHdlIHVzZSB0aGUgdmFyaWFuY2Ugb2YgJFxsblxmcmFje3NwTExfTX17c3BTU19NfSQgZm9yIHNpbXBsaWNpdHkgPGJyPg0KDQpXZSBzdGF0aXN0aWNhbGx5IGNvbXBhcmVkIHRob3NlIGVmZmVjdCBzaXplcyB0aHJvdWdoIHRoZSBmb3JtYWwgbWV0YS1yZWdyZXNzaW9uIGJ5IHVzaW5nIGBybWEubXZgIGZ1bmN0aW9uIG9mIFIgcGFja2FnZSBgbWV0YWZvcmAgPGJyPg0KDQpBbGwgbWV0YS1hbmFseXRpYyBtb2RlbHMgaW5jbHVkZWQgZm9sbG93aW5nIFJhbmRvbSBlZmZlY3RzIGVzdGltYXRlczogDQoNCiogYFN0dWR5LklEYDogUHJpbWFyeSBzdHVkaWVzLiBEZW5vdGVkIGFzICoqU3R1ZHkqKg0KDQoqIGBDcm9zcy5JRGA6IFBhcmVudGFsIHN0cmFpbiB1c2VkIGluIHRoZSBjcm9zc2luZy4gRGlzY3JpbWluYXRlIGludHJhc3BlY2lmaWMgcG9wdWxhdGlvbnMuIERlbm90ZWQgYXMgKipjcm9zc2VkIHN0cmFpbioqDQoNCiogYHNwTC5uYW1lYDogUGh5bG9nZW55IG9mIHBhcmVudGFsIHNwZWNpZXMgKDxpPnNwTEw8c3ViPk08L3N1Yj48L2k+KS4gRGVub3RlZCBhcyAqKnNwZWNpZXMgd2l0aCBwaHlsb2dlbnkqKg0KDQpgYGB7cn0NCg0KIysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysjDQojIENhbGN1bGF0ZSBtaWRwYXJlbnQgDQojKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyMNCm1pZHBhcmVudCA8LSBOb3ZlbC5Ob25ub3ZlbCAlPiUNCiAgIyBEaXZpZGUgbWVhbiBieSAyIGluIHNwTCB3aGVyZWFzIGh5YnJpZHMgYXJlIGNvbnN0YW50DQogIG11dGF0ZSgNCiAgICBsblJSLm1pZHBhcmVudC5lcyA9IA0KICAgICAgaWZlbHNlKA0KICAgICAgICBjcm9zcyA9PSAic3BMIiwNCiAgICAgICAgbG9nKCgoTW4uc3BMICsgTW4uc3BTKS8yKS9Nbi5zcFMpLCBsblJSLmVzDQogICAgICAgICkNCiAgICAjIERpdmlkZSB2YXJpYW5jZSBieSA0IGluIHNwTCB3aGVyZWFzIGh5YnJpZHMgYXJlIGNvbnN0YW50DQogICAgKSAlPiUNCiAgbXV0YXRlX2F0KCJjcm9zcyIsIGFzLmZhY3RvcikgJT4lDQogIHdpdGhpbihsZXZlbHMoY3Jvc3MpIDwtIGMoImh5YkxTIiwgImh5YlNMIiwgIm1pZHBhcmVudCIpKQ0KDQoNCiMrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysjDQojIENvbXBhcmUgbWlkcGFyZW50IGFuZCBoeWJyaWRzIGJ5IG1ldGEtcmVncmVzc29uDQojKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrIw0KZm9yICh0ciBpbiBjKCJBbGx0cmFpdHMiLCAiTm9ubm92ZWx0cmFpdHMiKSkgew0KICBmb3IgKHRheG9uIGluIGMoImFsbHRheG9uIiwgImluc2VjdCIpKSB7DQogICAgDQogICAgaWYgKHRheG9uID09ICJhbGx0YXhvbiIpIHsNCiAgICAgIGRhdCA8LSBtaWRwYXJlbnQgJT4lIA0KICAgICAgICBmaWx0ZXIoZGF0YS50eXBlID09IHRyKQ0KICAgIH0gZWxzZSB7DQogICAgICBkYXQgPC0gbWlkcGFyZW50ICU+JSANCiAgICAgICAgZmlsdGVyKGRhdGEudHlwZSA9PSB0ciwgaW5zZWN0ID09IHRheG9uKQ0KICAgIH0NCiAgDQogICAgIyAjIyBwaHlsb2dlbmV0aWMgcmFuZG9tIHJlZ3Jlc3NvbiBjb21wYXJpbmcgd2l0aCBtaWRwYXJlbnQgIyMjDQogICAgIyBtaWRwYXJlbnQuY29tcGFyZSA8LSBybWEubXYoDQogICAgIyAgIHlpID0gbG5SUi5taWRwYXJlbnQuZXMsDQogICAgIyAgIFYgPSBsblJSLnN2LA0KICAgICMgICBkYXRhID0gZGF0LA0KICAgICMgICBtZXRob2QgPSAiUkVNTCIsDQogICAgIyAgIHJhbmRvbSA9IGxpc3QofjEgfCBzcEwubmFtZSwgfjEgfCBTdHVkeS5JRCwgfjEgfCBDcm9zcy5JRCwgfjEgfCBFUy5JRCksDQogICAgIyAgIFIgPSBsaXN0KHNwTC5uYW1lID0gcGh5bG9fY29yKSwNCiAgICAjICAgbW9kcyA9IH4gcmVsZXZlbChjcm9zcywgcmVmID0gIm1pZHBhcmVudCIpDQogICAgIyAgICkNCiAgICAjICMjIFNhdmUgbW9kZWwgIyMjDQogICAgIyBzYXZlUkRTKA0KICAgICMgICBtaWRwYXJlbnQuY29tcGFyZSwNCiAgICAjICAgZmlsZSA9IHBhc3RlKCIuLi9BbmFseXNpcy9NZWFuLm1pZHBhcmVudC5jb21wYXJlIiwgdHIsIHRheG9uLCAib2JqIiwgc2VwID0gIi4iKQ0KICAgICMgICApDQoNCiAgICAjIyBMb2FkIG1vZGVsICMjIw0KICAgIG1pZHBhcmVudC5jb21wYXJlIDwtIHJlYWRSRFMoDQogICAgICBwYXN0ZSgiLi4vQW5hbHlzaXMvTWVhbi5taWRwYXJlbnQuY29tcGFyZSIsIHRyLCB0YXhvbiwgIm9iaiIsIHNlcCA9ICIuIikNCiAgICAgICkNCiAgICBhc3NpZ24oDQogICAgICBwYXN0ZSgiRG9taW5hbmNlIiwgdHIsIHRheG9uLCBzZXAgPSAiLiIpLA0KICAgICAgbWlkcGFyZW50LmNvbXBhcmUgJT4lIA0KICAgICAgICBnZXRfcmVnKCkgJT4lDQogICAgICAgICMgU2hvdyBkYXRhc2V0IG5hbWUNCiAgICAgICAgd2l0aGluKERhdGFzZXQgPC0gYyhwYXN0ZSh0ciwgdGF4b24pLCByZXAoIiIsIGxlbmd0aCguJEVzdGltYXRlKS0xKSkpICU+JQ0KICAgICAgICAjIFJlbmFtZSBmaXhlZCBlZmZlY3RzDQogICAgICAgIHdpdGhpbignRml4ZWQgZWZmZWN0cycgPC0gYygiIiwgIm1pZHBhcmVudCAoaW50cmNwdCkiLCAiaHliTFMiLCAiaHliU0wiKSkgJT4lDQogICAgICAgICMgRGlmZmVyZW5jZSBvZiBlYWNoIGNyb3NzIGZyb20gbWlkcGFyZW50IGluICUNCiAgICAgICAgbXV0YXRlKCdDb21wYXJpc29uIHdpdGggbWlkcGFyZW50JyA9IGMoDQogICAgICAgICAgcmVwKCIiLCAyKSwNCiAgICAgICAgICBwYXN0ZSgNCiAgICAgICAgICAgIHJvdW5kKA0KICAgICAgICAgICAgMTAwKihleHAobWlkcGFyZW50LmNvbXBhcmUkYmV0YVsxXSttaWRwYXJlbnQuY29tcGFyZSRiZXRhWzJdKSAgICAgICAgICAgIC1leHAobWlkcGFyZW50LmNvbXBhcmUkYmV0YVsxXSkpLCAjIGh5YnJpZCBMUw0KICAgICAgICAgICAgMiksDQogICAgICAgICAgICAiJSBsYXJnZXIiDQogICAgICAgICAgICApLA0KICAgICAgICAgIHBhc3RlKA0KICAgICAgICAgICAgcm91bmQoDQogICAgICAgICAgICAxMDAqKGV4cChtaWRwYXJlbnQuY29tcGFyZSRiZXRhWzFdK21pZHBhcmVudC5jb21wYXJlJGJldGFbM10pLWV4cChtaWRwYXJlbnQuY29tcGFyZSRiZXRhWzFdKSksICMgaHlicmlkIFNMDQogICAgICAgICAgICAyKSwNCiAgICAgICAgICAgICIlIGxhcmdlciINCiAgICAgICAgICAgICkNCiAgICAgICAgICApKQ0KICAgICAgKQ0KICAgIA0KICAgICMgIyMgTWV0YS1hbmFseXNpcyBmb3IgbWlkcGFyZW50IHRvIHBsb3QgYmFuZCAjIyMNCiAgICAjIG1pZHBhcmVudC5yYW5kb20gPC0gcm1hLm12KA0KICAgICMgICB5aSA9IGxuUlIubWlkcGFyZW50LmVzLA0KICAgICMgICBWID0gbG5SUi5zdiwNCiAgICAjICAgZGF0YSA9IGRhdCAlPiUgZmlsdGVyKGNyb3NzID09ICJtaWRwYXJlbnQiKSwNCiAgICAjICAgbWV0aG9kID0gIlJFTUwiLA0KICAgICMgICByYW5kb20gPSBsaXN0KH4xIHwgc3BMLm5hbWUsIH4xIHwgU3R1ZHkuSUQsIH4xIHwgQ3Jvc3MuSUQsIH4xIHwgRVMuSUQpLA0KICAgICMgICBSID0gbGlzdChzcEwubmFtZSA9IHBoeWxvX2NvcikNCiAgICAjICAgKQ0KICAgICMgIyMgU2F2ZSBtb2RlbCAjIyMNCiAgICAjIHNhdmVSRFMoDQogICAgIyAgIG1pZHBhcmVudC5yYW5kb20sDQogICAgIyAgIGZpbGUgPSBwYXN0ZSgiLi4vQW5hbHlzaXMvTWVhbi5taWRwYXJlbnQiLCB0ciwgdGF4b24sICJvYmoiLCBzZXAgPSAiLiIpDQogICAgIyAgICkNCg0KICB9DQp9DQoNCmJpbmRfcm93cygNCiAgRG9taW5hbmNlLkFsbHRyYWl0cy5hbGx0YXhvbiwgRG9taW5hbmNlLk5vbm5vdmVsdHJhaXRzLmFsbHRheG9uLA0KICBEb21pbmFuY2UuQWxsdHJhaXRzLmluc2VjdCwgRG9taW5hbmNlLk5vbm5vdmVsdHJhaXRzLmluc2VjdA0KICApICU+JQ0KICBrYWJsZSgiaHRtbCIsIGRpZ2l0cyA9IDMsIGNhcHRpb24gPSAiVGFibGUgUzMuIFJlc3VsdHMgb2YgbWV0YS1hbmFseXNpcyBpbnZlc3RpZ2F0aW5nIGRvbWluYW5jZSBpbiBwaGVub3R5cGljIG1lYW5zIHVzaW5nIGZ1bGwgZGF0YXNldCBvciBkYXRhIHN1YnNldHMiKSAlPiUgDQogIGthYmxlX3N0eWxpbmcoInN0cmlwZWQiLCBwb3NpdGlvbiA9ICJsZWZ0IikgJT4lDQogIHNjcm9sbF9ib3god2lkdGggPSAiMTAwJSIsIGhlaWdodCA9ICI1MDBweCIpDQoNCmBgYA0KDQoNCjxkaXYgc3R5bGU9Im1hcmdpbi1ib3R0b206NzBweDsiPg0KPC9kaXY+DQoNCiMjIFVuaXZhcmF0ZSBtZXRhLWFuYWx5c2lzIGZvciBlYWNoIGNyb3NzDQpRdWFudGlmeSBhbmQgdmlzdWFsaXNlIG92ZXJhbGwgdHJlbmQgb2YgcGhlbm90eXBpYyBtZWFuIG9mIGh5YnJpZHMgY29tcGFyZWQgdG8gcGFyZW50cyA8YnI+DQpNZXRhLWFuYWx5c2lzIHdhcyByZXBlYXRlZCBmb3Igc3Vic2V0IGRhdGEgLSBpbmNsdWRpbmcgb25seSBub24tbm92ZWwgcGhlbm90eXBlcywgb25seSBpbnNlY3RzLCBhbmQgbm9uLW5vdmVsIHBoZW5vdHlwZXMgaW4gaW5zZWN0cyA8YnI+DQpNZXRhLWFuYWx5c2lzIHdhcyBjb25kdWN0ZWQgYnkgdXNpbmcgYHJtYS5tdmAgZnVuY3Rpb24gaW4gYG1ldGFmb3JgIHBhY2thZ2UgPGJyPg0KDQoqQ29uZmlkZW50aWFsIGludGVydmFsIDogdGhpY2sgbGluZSAgDQoNCipQcmVkaWN0aW9uIGludGVydmFsIDogdGhpbiBsaW5lDQoNCmBgYHtyLCBmaWcuaGVpZ2h0ID0gNCwgZmlnLndpZHRoID0gNn0NCg0KY2FwIDwtIGRhdGEuZnJhbWUoDQogIERlc2NyaXB0aW9uID0gYygNCiAgICAiT3JjaGFyZCBwbG90IGZvciBmdWxsIGRhdGEgXG4oQWxsdHJhaXRzIGFsbHRheG9uKSIsIA0KICAgICJPcmNoYXJkIHBsb3QgZm9yIHN1YnNldCBkYXRhOlxuIEV4Y2x1ZGluZyB2ZXJ0ZWJyYXRlcyBcbihBbGx0cmFpdHMgaW5zZWN0KSIsDQogICAgIk9yY2hhcmQgcGxvdCBmb3Igc3Vic2V0IGRhdGE6XG4gSW5jbHVkaW5nIGFsbCB0YXhvbiBidXQgZXhjbHVkaW5nIG5vdmVsIHBoZW5vdHlwZSBcbihOb25ub3ZlbHRyYWl0cyBhbGx0YXhvbikiLA0KICAgICJPcmNoYXJkIHBsb3QgZm9yIHN1YnNldCBkYXRhOlxuIEV4Y2x1ZGluZyB2ZXJ0ZWJyYXRlcyBhbmQgbm92ZWwgcGhlbm90eXBlXG4gKE5vbm5vdmVsdHJhaXRzIGluc2VjdCkiDQogICAgKQ0KICApICU+JQ0KICBtdXRhdGVfYWxsKGFzLmNoYXJhY3RlcikNCnJvdy5uYW1lcyhjYXApIDwtIGMoIkFsbHRyYWl0cy5hbGx0YXhvbiIsICJBbGx0cmFpdHMuaW5zZWN0IiwgDQogICAgICAgICAgICAgIk5vbm5vdmVsdHJhaXRzLmFsbHRheG9uIiwgIk5vbm5vdmVsdHJhaXRzLmluc2VjdCIpDQoNCmZvciAodHIgaW4gYygiQWxsdHJhaXRzIiwgIk5vbm5vdmVsdHJhaXRzIikpIHsNCiAgZm9yICh0YXhvbiBpbiBjKCJhbGx0YXhvbiIsICJpbnNlY3QiKSkgew0KICAgIA0KICAgIGlmICh0YXhvbiA9PSAiYWxsdGF4b24iKSB7DQogICAgICBkYXQgPC0gTm92ZWwuTm9ubm92ZWwgJT4lDQogICAgICAgIGZpbHRlcihjcm9zcyA9PSBjciwgZGF0YS50eXBlID09IHRyKQ0KICAgIH0gZWxzZSB7DQogICAgICBkYXQgPC0gTm92ZWwuTm9ubm92ZWwgJT4lDQogICAgICAgIGZpbHRlcihjcm9zcyA9PSBjciwgZGF0YS50eXBlID09IHRyLCBpbnNlY3QgPT0gdGF4b24pDQogICAgfQ0KICAgIA0KICAgIHJlcy5tYSA8LSBmb3JlYWNoKA0KICAgICAgY3IgPSBjKCJzcEwiLCAiaHliTFMiLCAiaHliU0wiKSwgLmNvbWJpbmUgPSBgcmJpbmRgDQogICAgICApICVkbyUgew0KICAgICAgIyAjIFBoeWxvZ2VuZXRpYyByYW5kb20gbWV0YS1hbmFseXNpcw0KICAgICAgIyBwaHlsLnJhbmRvbSA8LSBybWEubXYoDQogICAgICAjICAgeWkgPSBsblJSLmVzLCBWID0gbG5SUi5zdiwNCiAgICAgICMgICBkYXRhID0gZGF0LCBtZXRob2QgPSAiUkVNTCIsDQogICAgICAjICAgcmFuZG9tID0gbGlzdCgNCiAgICAgICMgICAgIH4xIHwgc3BMLm5hbWUsIH4xIHwgU3R1ZHkuSUQsIH4xIHwgQ3Jvc3MuSUQsIH4xIHwgRVMuSUQNCiAgICAgICMgICAgICksDQogICAgICAjICAgUiA9IGxpc3Qoc3BMLm5hbWUgPSBwaHlsb19jb3IpDQogICAgICAjICAgKQ0KICAgICAgIyBzYXZlUkRTKHBoeWwucmFuZG9tLA0KICAgICAgIyAgIGZpbGUgPSBwYXN0ZSgiLi4vQW5hbHlzaXMvTWVhbi5tZXRhIiwgdHIsIHRheG9uLCBjciwgIm9iaiIsIHNlcCA9ICIuIikpDQoNCiAgICAgICMgY3JlYXRpbmcgc3VtbWFyeSB0YWJsZSBvZiByZXN1bHRzDQogICAgICByZWFkUkRTKA0KICAgICAgICBwYXN0ZSgiLi4vQW5hbHlzaXMvTWVhbi5tZXRhIiwgdHIsIHRheG9uLCBjciwgIm9iaiIsIHNlcCA9ICIuIikNCiAgICAgICAgKSAlPiUNCiAgICAgICAgICBnZXRfcHJlZCgpICU+JQ0KICAgICAgICAgIGFzLmRhdGEuZnJhbWUoKSAlPiUNCiAgICAgICAgICBtdXRhdGUoDQogICAgICAgICAgICBOID0gbGVuZ3RoKGRhdCRFUy5JRCksDQogICAgICAgICAgICAjIEkyID0gSTIocGh5bC5yYW5kb20pWyJJMl90b3RhbCJdICU+JSByb3VuZCgzKSwNCiAgICAgICAgICAgIGNyb3NzID0gY3IgIyBpbmRpY2F0ZSBjcm9zcyAoc3BMLCBoeWJMUywgaHliU0wpDQogICAgICAgICAgICApICU+JSANCiAgICAgICAgYXMuZGF0YS5mcmFtZSgpICU+JQ0KICAgICAgICB3aXRoaW4oJ0RhdGFzZXQnIDwtIGMocGFzdGUodHIsIHRheG9uKSwgIiIsICIiKSkgJT4lICAjIGRhdGFzZXQgbmFtZSBpbiBmaXJzdCByb3cNCiAgICAgICAgcmV0dXJuKCkNCiAgICAgICAgfQ0KICAgIA0KICAgIGlmICh0YXhvbiA9PSAiYWxsdGF4b24iKSB7DQogICAgICBkYXQucGxvdCA8LSBOb3ZlbC5Ob25ub3ZlbCAlPiUgDQogICAgICAgIGZpbHRlcihkYXRhLnR5cGUgPT0gdHIpDQogICAgfSBlbHNlIHsNCiAgICAgIGRhdC5wbG90IDwtIE5vdmVsLk5vbm5vdmVsICU+JSANCiAgICAgICAgZmlsdGVyKGRhdGEudHlwZSA9PSB0ciwgaW5zZWN0ID09IHRheG9uKQ0KICAgIH0NCg0KICAgICMgQmluZCByZXN1bHQgb2YgYWxsIGNyb3NzZXMgYXQgZWFjaCBkYXRhc2V0DQogICAgYXNzaWduKA0KICAgICAgcGFzdGUoInJlcy5tYSIsIHRyLCB0YXhvbiwgc2VwID0gIi4iKSwNCiAgICAgIHJlcy5tYQ0KICAgICkNCiAgICANCiAgICAjIyBNaWRwYXJlbnQgZXN0aW1hdGUgJiBDSSAjIyMNCiAgICBtaWRwYXJlbnQubWEuMiA8LSByZWFkUkRTKA0KICAgICAgcGFzdGUoIi4uL0FuYWx5c2lzL01lYW4ubWlkcGFyZW50IiwgdHIsIHRheG9uLCAib2JqIiwgc2VwID0gIi4iKQ0KICAgICAgKSAlPiUgDQogICAgICAjIFByZWRpY3Rpb24gaW50ZXJ2YWwgb2YgbWlkcGFyZW50DQogICAgICBnZXRfcHJlZCgpICU+JQ0KICAgICAgYXMuZGF0YS5mcmFtZSgpDQogICAgDQogICAgIyBjcmVhdGluZyBhIGZvcmVzdCBwbG90DQogICAgcGxvdC5tZXRhbWVhbiA8LSBnZ3Bsb3QoDQogICAgICBkYXRhID0gcmVzLm1hLCANCiAgICAgIGFlcyh4ID0gdGFuaChFc3RpbWF0ZSksIHkgPSBjcm9zcykNCiAgICAgICkgKw0KICAgICAgc2NhbGVfeV9kaXNjcmV0ZShleHBhbmQgPSBjKDAsIDEpKSArDQogICAgICBzY2FsZV94X2NvbnRpbnVvdXMoDQogICAgICAgIGxpbWl0cyA9IGMoLTEsIDEpLCANCiAgICAgICAgYnJlYWtzID0gc2VxKC0xLCAxLCBieSA9IDAuNSkNCiAgICAgICAgKSArIA0KICAgICAgIyMgTWlkcGFyZW50IENJICMjIw0KICAgICAgZ2VvbV9yZWN0KA0KICAgICAgICBhZXMoDQogICAgICAgICAgeG1pbiA9IHRhbmgobWlkcGFyZW50Lm1hLjIkTG93ZXJDSSksDQogICAgICAgICAgeG1heCA9IHRhbmgobWlkcGFyZW50Lm1hLjIkVXBwZXJDSSksDQogICAgICAgICAgeW1pbiA9IC1JbmYsIHltYXggPSBJbmYNCiAgICAgICAgICApLA0KICAgICAgICBmaWxsPSJHcmV5IDkwIg0KICAgICAgICApICsNCiAgICAgICMjIE1pZHBhcmVudCBlc3RpbWF0ZSAjIyMNCiAgICAgIGdlb21fdmxpbmUoDQogICAgICAgIHhpbnRlcmNlcHQgPSB0YW5oKG1pZHBhcmVudC5tYS4yJEVzdGltYXRlKSwgY29sb3VyID0gImdyZXkyMCIsIA0KICAgICAgICBhbHBoYSA9IDAuMywgc2l6ZSA9IDENCiAgICAgICAgKSArDQogICAgICAjIyBPcmNoYXJkIHBsb3QgIyMjDQogICAgICBnZW9tX3F1YXNpcmFuZG9tKA0KICAgICAgICBkYXRhID0gZGF0LnBsb3QsIA0KICAgICAgICBhZXMoeCA9IHRhbmgobG5SUi5lcyksIHkgPSBjcm9zcywgc2l6ZSA9IDEvbG5SUi5zdiwgY29sb3IgPSBjcm9zcyksIA0KICAgICAgICBhbHBoYSA9IDAuMiwgR3JvdXBPblggPSBGQUxTRQ0KICAgICAgICApICsgDQogICAgICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiI0RDMjY3RiIsICIjNzg1RUYwIiwgIiNGRTYxMDAiKSkgKw0KICAgICAgIyBEZWxldGUgbGVnZW5kIGZvciBjb2xvcnMNCiAgICAgIGd1aWRlcyhmaWxsID0gIm5vbmUiLCBjb2xvdXIgPSAibm9uZSIpICsNCiAgICAgICMgQ29uZmlkZW50aWFsIGludGVydmFsIDogdGhpY2tlciBsaW5lDQogICAgICBnZW9tX2Vycm9yYmFyaCgNCiAgICAgICAgYWVzKHhtaW4gPSB0YW5oKExvd2VyQ0kpLCB4bWF4ID0gdGFuaChVcHBlckNJKSksIA0KICAgICAgICBoZWlnaHQgPSAwLCBzaXplID0gMS4yLCBhbHBoYSA9IDAuNg0KICAgICAgICApICsgDQogICAgICAjIFByZWRpY3Rpb24gaW50ZXJ2YWwgOiB0aGlubmVyIGxpbmUNCiAgICAgIGdlb21fZXJyb3JiYXJoKA0KICAgICAgICBhZXMoeG1pbiA9IHRhbmgobG93ZXJQUiksIHhtYXggPSB0YW5oKHVwcGVyUFIpKSwgDQogICAgICAgIGhlaWdodCA9IDAuMSwgc2l6ZSA9IDAuNSwgYWxwaGEgPSAwLjYNCiAgICAgICAgKSArDQogICAgICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwLCBsaW5ldHlwZSA9IDIsIGNvbG91ciA9ICJibGFjayIsIGFscGhhID0gMC4zKSArDQogICAgICAjIyBFc3RpbWF0ZSAjIyMNCiAgICAgIGdlb21fcG9pbnQoc2l6ZSA9IDMsIHNoYXBlID0gMjEsIGZpbGwgPSAiYmxhY2siKSArIA0KICAgICAgIyAjIyBJXjIgIyMjDQogICAgICAjIGFubm90YXRlKA0KICAgICAgIyAgICJ0ZXh0IiwgeCA9IC0wLjkzLCB5ID0gYygxLjM1LCAyLjM1LCAzLjM1KSwNCiAgICAgICMgICBsYWJlbCA9IHBhc3RlKCJpdGFsaWMoSV4yKT09IiwgcmVzLm1hJEkyKSwgDQogICAgICAjICAgcGFyc2UgPSBUUlVFLCBoanVzdCA9ICJsZWZ0Iiwgc2l6ZSA9IDUNCiAgICAgICMgKSArIA0KICAgICAgIyMgTiAjIyMNCiAgICAgIGFubm90YXRlKA0KICAgICAgICAidGV4dCIsIHggPSAtMC45MywgeSA9IDMuODUsDQogICAgICAgIGxhYmVsID0gcGFzdGUoIml0YWxpYyhOKT09IiwgbGVuZ3RoKGRhdC5wbG90JEVTLklEKS8zKSwgDQogICAgICAgIHBhcnNlID0gVFJVRSwgaGp1c3QgPSAibGVmdCIsIHNpemUgPSA1DQogICAgICApICsgDQogICAgICBhbm5vdGF0ZSgNCiAgICAgICAgInRleHQiLCB4ID0gLTAuNjgsIHkgPSAzLjg1LA0KICAgICAgICBsYWJlbCA9ICJlYWNoIiwgaGp1c3QgPSAibGVmdCIsIHNpemUgPSA1DQogICAgICApICsgDQogICAgICB5bGFiKCIiKSArDQogICAgICB4bGFiKGV4cHJlc3Npb24oDQogICAgICAgIHBhc3RlKCJoeXBlcmJvbGljIHRhbmdlbnQgb2YgbG5SUiBmcm9tICIsIGl0YWxpYygic3BTUyIpKSwgDQogICAgICAgIHBhcnNlID0gVFJVRQ0KICAgICAgICApKSArDQogICAgICBnZ3RpdGxlKGNhcFtwYXN0ZSh0ciwgdGF4b24sc2VwPSIuIiksXSkgKw0KICAgICAgb3JjaGFyZHRoZW1lIA0KDQogICAgcHJpbnQocGxvdC5tZXRhbWVhbikNCiAgDQogICAgIyBnZ3NhdmUoDQogICAgIyAgIHBsb3QgPSBwbG90Lm1ldGFtZWFuLA0KICAgICMgICBmaWxlID0gcGFzdGUoIi4uL0FuYWx5c2lzL21lYW4uZ2VuZXJhbC5tZXRhbWVhbiIsIHRyLCB0YXhvbiwgInN2ZyIsIHNlcCA9ICIuIiksDQogICAgIyAgIGhlaWdodCA9IDQsIHdpZHRoID0gNQ0KICAgICMgICApDQogICAgDQogIH0NCn0NCg0KYmluZF9yb3dzKA0KICByZXMubWEuQWxsdHJhaXRzLmFsbHRheG9uLCByZXMubWEuTm9ubm92ZWx0cmFpdHMuYWxsdGF4b24sDQogIHJlcy5tYS5BbGx0cmFpdHMuaW5zZWN0LCByZXMubWEuTm9ubm92ZWx0cmFpdHMuaW5zZWN0DQogICkgJT4lDQogIGFzLmRhdGEuZnJhbWUoKSAlPiUNCiAgIyBtdXRhdGVfYXQodmFycygnRXN0aW1hdGUnOiclSTJbcmVzaWR1YWxdJyksIGFzLm51bWVyaWMpICU+JQ0KICAjIHNlbGVjdChEYXRhc2V0LCBjcm9zcywgRXN0aW1hdGUsIFVwcGVyQ0ksIExvd2VyQ0ksIGNvbnRhaW5zKCJQUiIpLCBjb250YWlucygiSTIiKSkgJT4lDQogIGthYmxlKCJodG1sIiwgZGlnaXRzID0gMywgY2FwdGlvbiA9ICJNZXRhLWFuYWx5c2VzIHJlc3VsdHMgb2YgZnVsbCBkYXRhc2V0IGFuZCBkYXRhIHN1YnNldHMiKSAlPiUgDQogIGthYmxlX3N0eWxpbmcoInN0cmlwZWQiLCBwb3NpdGlvbiA9ICJsZWZ0IikgJT4lDQogIHNjcm9sbF9ib3god2lkdGggPSAiMTAwJSIsIGhlaWdodCA9ICI1MDBweCIpDQoNCmBgYA0KDQoNCjxkaXYgc3R5bGU9Im1hcmdpbi1ib3R0b206NzBweDsiPg0KPC9kaXY+DQoNCiMjIENyb3NzaW5nIGRpcmVjdGlvbiBlZmZlY3QgaW4gcGhlbm90eXBpYyBtZWFucw0KDQpXZSBzdGF0aXN0aWNhbGx5IGNvbXBhcmVkIGxuUlIgZnJvbSA8aT5zcFNTPHN1Yj5NPC9zdWI+PC9pPiB0byB0aGUgb3RoZXIgY3Jvc3NlcyB0aHJvdWdoIHRoZSBmb3JtYWwgbWV0YS1yZWdyZXNzaW9uIGJ5IHVzaW5nIGBybWEubXZgIGZ1bmN0aW9uIG9mIFIgcGFja2FnZSBgbWV0YWZvcmAuIDxicj4gDQoNCkhlcmUgd2UgYXNrZWQgaWYgbG5SUiBvZiA8aT5oeWJTTDxzdWI+TTwvc3ViPjwvaT4gd2FzIHNtYWxsZXIvbGFyZ2VyIHRoYW4gdGhhdCBvZiA8aT5oeWJMUzxzdWI+TTwvc3ViPjwvaT4gPGJyPg0KDQpJZiAkXGxuXGZyYWN7aHlicmlkTFNfTX17c3BTU19NfT5cbG5cZnJhY3toeWJyaWRTTF9NfXtzcFNTX019JCwgPGk+aHlicmlkTFM8c3ViPk08L3N1Yj48L2k+IGhhcyBsYXJnZXIgcGhlbm90eXBpYyBtZWFuIHRoYW4gPGk+aHlicmlkU0w8c3ViPk08L3N1Yj48L2k+IC4uLm1hdGVybmFsIGluaGVyaXRhbmNlDQoNCg0KYGBge3J9DQoNCmZvciAodHIgaW4gYygiQWxsdHJhaXRzIiwgIk5vbm5vdmVsdHJhaXRzIikpIHsNCiAgZm9yICh0YXhvbiBpbiBjKCJhbGx0YXhvbiIsICJpbnNlY3QiKSkgew0KICAgIA0KICAgIGlmICh0YXhvbiA9PSAiYWxsdGF4b24iKSB7DQogICAgICBkYXQgPC0gTm92ZWwuTm9ubm92ZWwgJT4lIA0KICAgICAgICBmaWx0ZXIoZGF0YS50eXBlID09IHRyKQ0KICAgIH0gZWxzZSB7DQogICAgICBkYXQgPC0gTm92ZWwuTm9ubm92ZWwgJT4lIA0KICAgICAgICBmaWx0ZXIoZGF0YS50eXBlID09IHRyLCBpbnNlY3QgPT0gdGF4b24pDQogICAgfQ0KICANCiAgICAjICMrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysjDQogICAgIyAjIHBoeWxvZ2VuZXRpYyByYW5kb20gcmVncmVzc29uIChBTk9WQSkNCiAgICAjICMrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysjDQogICAgIyAjIFJlZ3Jlc3MgYnkgbG5SUiBvZiBwaGVub3R5cGljIGRpZmZlcmVuY2UgYmV0d2VlbiBwYXJlbnRhbHMNCiAgICAjIHBoeWwucmFuZG9tLnNwTCA8LSBybWEubXYoDQogICAgIyAgIHlpID0gbG5SUi5lcywgViA9IGxuUlIuc3YsDQogICAgIyAgIGRhdGEgPSBkYXQsIG1ldGhvZCA9ICJSRU1MIiwNCiAgICAjICAgcmFuZG9tID0gbGlzdCh+MSB8IHNwTC5uYW1lLCB+MSB8IFN0dWR5LklELCB+MSB8IENyb3NzLklELCB+MSB8IEVTLklEKSwNCiAgICAjICAgUiA9IGxpc3Qoc3BMLm5hbWUgPSBwaHlsb19jb3IpLA0KICAgICMgICBtb2RzID0gfiByZWxldmVsKGNyb3NzLCByZWYgPSAic3BMIikNCiAgICAjICAgKQ0KICAgICMgcGh5bC5yYW5kb20uaHliTFMgPC0gcm1hLm12KA0KICAgICMgICB5aSA9IGxuUlIuZXMsIFYgPSBsblJSLnN2LA0KICAgICMgICBkYXRhID0gZGF0LCBtZXRob2QgPSAiUkVNTCIsDQogICAgIyAgIHJhbmRvbSA9IGxpc3QofjEgfCBzcEwubmFtZSwgfjEgfCBTdHVkeS5JRCwgfjEgfCBDcm9zcy5JRCwgfjEgfCBFUy5JRCksDQogICAgIyAgIFIgPSBsaXN0KHNwTC5uYW1lID0gcGh5bG9fY29yKSwNCiAgICAjICAgbW9kcyA9IH4gY3Jvc3MNCiAgICAjICAgKQ0KICAgICMgIyBTYXZlIG1vZGVsICMjIw0KICAgICMgc2F2ZVJEUygNCiAgICAjICAgcGh5bC5yYW5kb20uc3BMLA0KICAgICMgICBmaWxlID0gcGFzdGUoIi4uL0FuYWx5c2lzL01lYW4uY29tcGFyZS5mcm9tLnNwTCIsIHRyLCB0YXhvbiwgIm9iaiIsIHNlcCA9ICIuIikNCiAgICAjICAgKQ0KICAgICMgc2F2ZVJEUygNCiAgICAjICAgcGh5bC5yYW5kb20uaHliTFMsDQogICAgIyAgIGZpbGUgPSBwYXN0ZSgiLi4vQW5hbHlzaXMvTWVhbi5jb21wYXJlLmZyb20uaHliTFMiLCB0ciwgdGF4b24sICJvYmoiLCBzZXAgPSAiLiIpDQogICAgIyAgICkNCiAgICANCiAgICBwaHlsLnJhbmRvbS5oeWJMUyA8LSByZWFkUkRTKA0KICAgICAgcGFzdGUoIi4uL0FuYWx5c2lzL01lYW4uY29tcGFyZS5mcm9tLmh5YkxTIiwgdHIsIHRheG9uLCAib2JqIiwgc2VwID0gIi4iKQ0KICAgICAgKSANCg0KICAgIGFzc2lnbigNCiAgICAgIHBhc3RlKCJSZWNpcHJvY2FsIiwgdHIsIHRheG9uLCBzZXAgPSAiLiIpLA0KICAgICAgcGh5bC5yYW5kb20uaHliTFMgJT4lIA0KICAgICAgICBnZXRfcmVnKCkgJT4lDQogICAgICAgICMgU2hvdyBkYXRhc2V0IG5hbWUNCiAgICAgICAgd2l0aGluKERhdGFzZXQgPC0gYyhwYXN0ZSh0ciwgdGF4b24pLCByZXAoIiIsIGxlbmd0aCguJEVzdGltYXRlKS0xKSkpICU+JQ0KICAgICAgICAjIFJlbmFtZSBmaXhlZCBlZmZlY3RzDQogICAgICAgIHdpdGhpbignRml4ZWQgZWZmZWN0cycgPC0gYygiIiwgImh5YkxTIChpbnRyY3B0KSIsICJoeWJTTCIsICJzcExMIikpICU+JQ0KICAgICAgICAjIERpZmZlcmVuY2Ugb2YgZWFjaCBjcm9zcyBmcm9tIG1pZHBhcmVudCBpbiAlDQogICAgICAgIG11dGF0ZSgnQ29tcGFyaXNvbiB3aXRoIGh5YnJpZExTJyA9IGMoDQogICAgICAgICAgcmVwKCIiLCAyKSwNCiAgICAgICAgICBwYXN0ZSgNCiAgICAgICAgICAgIHJvdW5kKA0KICAgICAgICAgICAgICAoZXhwKHBoeWwucmFuZG9tLmh5YkxTJGJldGFbMV0rcGh5bC5yYW5kb20uaHliTFMkYmV0YVsyXSkgLQ0KICAgICAgICAgICAgICAgICBleHAocGh5bC5yYW5kb20uaHliTFMkYmV0YVsxXSkNCiAgICAgICAgICAgICAgICkqMTAwLA0KICAgICAgICAgICAgICAyKSwNCiAgICAgICAgICAgICIlIGxhcmdlciINCiAgICAgICAgICAgICksIA0KICAgICAgICAgICIiDQogICAgICAgICAgKQ0KICAgICAgICApDQogICAgICApDQogIH0NCn0NCg0KYmluZF9yb3dzKA0KICBSZWNpcHJvY2FsLkFsbHRyYWl0cy5hbGx0YXhvbiwgUmVjaXByb2NhbC5Ob25ub3ZlbHRyYWl0cy5hbGx0YXhvbiwNCiAgUmVjaXByb2NhbC5BbGx0cmFpdHMuaW5zZWN0LCBSZWNpcHJvY2FsLk5vbm5vdmVsdHJhaXRzLmluc2VjdA0KICApICU+JQ0KICBrYWJsZSgiaHRtbCIsIGRpZ2l0cyA9IDMsIGNhcHRpb24gPSAiVGFibGUgUzQuIFJlc3VsdHMgb2YgbWV0YS1hbmFseXNpcyBpbnZlc3RpZ2F0aW5nIGNyb3NzaW5nIGRpcmVjdGlvbiBlZmZlY3RzIGluIHBoZW5vdHlwaWMgbWVhbnMgdXNpbmcgZnVsbCBkYXRhc2V0IG9yIGRhdGEgc3Vic2V0cyIpICU+JSANCiAga2FibGVfc3R5bGluZygic3RyaXBlZCIsIHBvc2l0aW9uID0gImxlZnQiKSAlPiUNCiAgc2Nyb2xsX2JveCh3aWR0aCA9ICIxMDAlIiwgaGVpZ2h0ID0gIjUwMHB4IikNCg0KYGBgDQoNCg0KDQoNCjxkaXYgc3R5bGU9Im1hcmdpbi1ib3R0b206MTgwcHg7Ij4NCjwvZGl2Pg0KIyBNZXRhLWFuYWx5c2lzIGZvciBwaGVub3R5cGljIHZhcmlhdGlvbiAoY29lZmZpY2llbnQgb2YgdmFyaWF0aW9uIC0gQ1YpDQoNCldlIGNyZWF0ZWQgZGF0YSBzdWJzZXQgYWNjb3JkaW5nIHRvIHRheG9uIChhbGwgdGF4b24gb3IgaW5zZWN0IG9ubHkpIGFuZCBub3ZlbHR5IGluIHBoZW5vdHlwaWMgdmFyaWFiaWxpdGllcyAoYWxsIHRyYWl0cyBvciBub24tbm92ZWwgdHJhaXRzIC0gdHJhaXQgdmFyaWFiaWxpdHkgW2luIHRlcm1zIG9mIGNvZWZmaWNpZW50IG9mIHZhcmlhdGlvbl0gb2YgaHlicmlkcyBkb2VzIG5vdCBleGNlZWQgc2l6ZSByYW5nZSBvZiBwYXJlbnRzKS4gV2UgY29uZHVjdCBpZGVudGljYWwgYW5hbHlzZXMgZm9yIGZ1bGwgZGF0YSBhbmQgZGF0YSBzdWJzZXRzLCBhbmQgY2hlY2tlZCByb2J1c3RuZXNzIG9mIG91ciByZXN1bHRzLg0KDQojIyBFZmZlY3Qgc2l6ZSBjYWxjdWxhdGlvbg0KDQpXZSBxdWFudGlmaWVkIHJlbGF0aXZlIHBoZW5vdHlwaWMgdmFyaWFiaWxpdHkgb2YgaHlicmlkcyBhbmQgdGhlIHBhcmVudCB3aXRoIGxhcmdlIHZhcmlhYmlsaXR5ICg8aT5zcExMPHN1Yj5WPC9zdWI+PC9pPikgdG8gdGhlIHBhcmVudCB3aXRoIHNtYWxsIHZhcmlhYmlsaXR5ICg8aT5zcFNTPHN1Yj5WPC9zdWI+PC9pPiksIGJ5IHVzaW5nIFtsbkNWUl0gIChodHRwczovL2Jlc2pvdXJuYWxzLm9ubGluZWxpYnJhcnkud2lsZXkuY29tL2RvaS9mdWxsLzEwLjExMTEvMjA0MS0yMTBYLjEyMzA5KSAoQE5ha2FnYXdhMjAxNSkuIFdlIGNvbnRyb2xsZWQgbWVhbi12YXJpYW5jZSByZWxhdGlvbnNoaXAgYnkgdXNpbmcgQ29lZmZpY2llbnQgb2YgVmFyaWF0aW9uIChDVikgYXMgdGhlIHByb3h5IG9mIHBoZW5vdHlwaWMgdmFyaWFiaWxpdHkuIDxicj4NCkVmZmVjY3Qgc2l6ZSB3YXMgY2FsY3VsYXRlZCBieSB1c2luZyBgZXNjYWxjYCBmdW5jdGlvbiBpbiBgbWV0YWZvcmAgcGFja2FnZSANCg0KYGBge3J9DQoNCiMgbG9hZCBzcExTIGZpbGVzDQpkYXQgPC0gcmVhZC5jc3YoIi4uL2RhdGEvZGF0LkNWLmNzdiIsIGhlYWQgPSBUUlVFKQ0KDQojIE9yZGVyIGJ5IHRheG9uDQpkYXQkdGF4YSA8LSBvcmRlcmVkKA0KICBkYXQkdGF4YSwNCiAgbGV2ZWxzID0gYygiTmV1cm9wdGVyYSIsICJDb2xlb3B0ZXJhIiwgIkRpcHRlcmEiLCAiTGVwaWRvcHRlcmEiLCAiT3J0aG9wdGVyYSIsICJBdmVzIiwgIlJvZGVudGlhIiwgIkFudXJhIiwgIkNpY2hsaWZvcm1lcyIpDQogICkNCg0KdmFyLmRpZiA8LSBmb3JlYWNoKA0KICBjciA9IGMoImh5YkxTIiwgImh5YlNMIiwgInNwTCIpLCANCiAgLmNvbWJpbmUgPSBgcmJpbmRgDQogICkgJWRvJSB7DQogICAgZXNjYWxjKA0KICAgICAgbWVhc3VyZSA9ICJDVlIiLA0KICAgICAgIyBOIG9mIGh5YnJpZHMNCiAgICAgIG4xaSA9IGRhdFssIHBhc3RlKCJOIiwgY3IsIHNlcCA9ICIuIildLA0KICAgICAgIyBOIG9mIHBhcmVudGFscw0KICAgICAgbjJpID0gZGF0WywgIk4uc3BTIl0sDQogICAgICAjIE1lYW4gb2YgaHlicmlkcw0KICAgICAgbTFpID0gZGF0WywgcGFzdGUoIk1uIiwgY3IsIHNlcCA9ICIuIildLA0KICAgICAgIyBNZWFuIG9mIHBhcmVudGFscw0KICAgICAgbTJpID0gZGF0WywgIk1uLnNwUyJdLA0KICAgICAgIyBTRCBvZiBoeWJyaWRzDQogICAgICBzZDFpID0gZGF0WywgcGFzdGUoIlNEIiwgY3IsIHNlcCA9ICIuIildLA0KICAgICAgIyBTRCBvZiBwYXJlbnRhbHMNCiAgICAgIHNkMmkgPSBkYXRbLCAiU0Quc3BTIl0sDQogICAgICBkYXRhID0gZGF0DQogICAgICApICU+JQ0KICAgIHJlbmFtZShsbkNWUi5lcyA9IHlpLCBsbkNWUi5zdiA9IHZpKSAlPiUNCiAgICBtdXRhdGUoY3Jvc3MgPSBjcikNCiAgfSAlPiUgDQogIGRyb3BfbmEobG5DVlIuZXMpICU+JQ0KICBhcnJhbmdlKEVTLklEKSAlPiUNCiAgbGVmdF9qb2luKC4sIGRhdCkNCg0KYGBgDQoNCiMjIEZ1bm5lbCBwbG90cw0KDQpgYGB7cn0NCg0KcmVzIDwtIHJtYSh5aSA9IGxuQ1ZSLmVzLCB2aSA9IGxuQ1ZSLnN2LCBkYXRhID0gdmFyLmRpZiwgbWV0aG9kPSJGRSIpDQoNCiMjIHNldCB1cCAyeDIgYXJyYXkgZm9yIHBsb3R0aW5nDQpwYXIobWZyb3c9YygyLDIpKQ0KIyMgZHJhdyBmdW5uZWwgcGxvdHMNCmZ1bm5lbChyZXMsIG1haW49IlN0YW5kYXJkIEVycm9yIiwgeGxpbSA9IGMoLTUsIDUpKQ0KZnVubmVsKHJlcywgeWF4aXM9InZpIiwgbWFpbj0iU2FtcGxpbmcgVmFyaWFuY2UiLCB4bGltID0gYygtNSwgNSkpDQpmdW5uZWwocmVzLCB5YXhpcz0ic2VpbnYiLCBtYWluPSJJbnZlcnNlIFN0YW5kYXJkIEVycm9yIiwgeGxpbSA9IGMoLTUsIDUpKQ0KZnVubmVsKHJlcywgeWF4aXM9InZpbnYiLCBtYWluPSJJbnZlcnNlIFNhbXBsaW5nIFZhcmlhbmNlIiwgeGxpbSA9IGMoLTUsIDUpKQ0KDQpgYGANCg0KIyMgQ2hlY2sgZGF0YQ0KDQpDaGVja2VkIGVmZmVjdCBzaXplcyB3aXRoIGV4dHJlbWVseSBoaWdoL2xvdyBzdGFuZGFyZCBlcnJvciAoU0UgPiAxLjIgfCAxL1NFID4gOC41KSBhbmQgY29uZmlybWVkIHRoYXQgdGhvc2UgZGF0YSB3ZXJlIGNvcnJlY3RseSBpbXBvcnRlZC4gDQoNCmBgYHtyLCByZXN1bHRzPSdhc2lzJ30NCg0Kb3V0bGllcnMgPC0gdmFyLmRpZiAlPiUNCiAgIyB2aSAoc2FtcGxpbmcgdmFyaWFuY2UpIA0KICBtdXRhdGUoU0UgPSBzcXJ0KGxuQ1ZSLnN2KSkgJT4lDQogIGFycmFuZ2UoZGVzYyhTRSkpICU+JQ0KICBmaWx0ZXIoU0UgPiAxLjIgfCAxL1NFID4gOC41KSAlPiUNCiAgc2VsZWN0KEVTLklELCBTdHVkeS5uYW1lLCBTRSwgY3Jvc3MsIFJlY2lwcm9jYWwsIHRyYWl0LCBDcm9zcy5JRCkgJT4lDQogIG11dGF0ZV9pZihpcy5udW1lcmljLCByb3VuZCwgMykNCg0Kb3V0bGllcnMgJT4lDQogIGthYmxlKCJodG1sIiwgZGlnaXRzID0gMywgY2FwdGlvbiA9ICJFZmZlY3Qgc2l6ZXMgd2l0aCBleHRyZW1lbHkgaGlnaC9sb3cgc3RhbmRhcmQgZXJyb3IgKFNFID4gMS4yIHwgMS9TRSA+IDE0MCkiKSAlPiUgDQogIGthYmxlX3N0eWxpbmcoInN0cmlwZWQiLCBwb3NpdGlvbiA9ICJsZWZ0IikgJT4lDQogIHNjcm9sbF9ib3god2lkdGggPSAiMTAwJSIsIGhlaWdodCA9ICI1MDBweCIpDQoNCnZhci5kaWYuMiA8LSB2YXIuZGlmICU+JQ0KICBmaWx0ZXIoIUVTLklEICVpbiUgdW5pcXVlKG91dGxpZXJzJEVTLklEKSkgDQp3cml0ZS5jc3YodmFyLmRpZi4yLCAiLi4vZGF0YS92YXJpYXRpb24uRVMuZ2VuZXJhbC5jc3YiLCByb3cubmFtZXMgPSBGKQ0KDQpgYGANCkJlY2F1c2UgdGhleSBpbmhpYml0IG1ldGEtYW5hbHl0aWMgbW9kZWwgY29udmVyZ2VuY2UsIHdlIGV4Y2x1ZGVkIHRoZXNlIG91dGxpZXJzIGZyb20gdGhlIGZvcm1hbCBtZXRhLWFuYWx5c2lzIGRhdGFzZXQsIGJ1dCBub3QgZnJvbSBub3ZlbCB2YXJpYWJpbGl0eSBkYXRhc2V0Lg0KDQoNCiMjIEZ1bm5lbCBwbG90cyBhZ2Fpbg0KRnVubmVsIHBsb3RzIGFmdGVyIG91dGxpZXJzIGV4Y2x1ZGVkDQpgYGB7cn0NCg0KcmVzIDwtIHJtYSh5aSA9IGxuQ1ZSLmVzLCB2aSA9IGxuQ1ZSLnN2LCBkYXRhID0gdmFyLmRpZi4yLCBtZXRob2Q9IkZFIikNCiMjIHNldCB1cCAyeDIgYXJyYXkgZm9yIHBsb3R0aW5nDQpwYXIobWZyb3c9YygyLDIpKQ0KIyMgZHJhdyBmdW5uZWwgcGxvdHMNCmZ1bm5lbChyZXMsIG1haW49IlN0YW5kYXJkIEVycm9yIiwgeGxpbSA9IGMoLTUsIDUpKQ0KZnVubmVsKHJlcywgeWF4aXM9InZpIiwgbWFpbj0iU2FtcGxpbmcgVmFyaWFuY2UiLCB4bGltID0gYygtNSwgNSkpDQpmdW5uZWwocmVzLCB5YXhpcz0ic2VpbnYiLCBtYWluPSJJbnZlcnNlIFN0YW5kYXJkIEVycm9yIiwgeGxpbSA9IGMoLTUsIDUpKQ0KZnVubmVsKHJlcywgeWF4aXM9InZpbnYiLCBtYWluPSJJbnZlcnNlIFNhbXBsaW5nIFZhcmlhbmNlIiwgeGxpbSA9IGMoLTUsIDUpKQ0KDQpgYGANCg0KDQojIyBKdWdkaW5nIG5vdmVsdHkgaW4gcGhlbm90eXBpYyB2YXJpYWJpbGl0aWVzICh1c2luZyBDVikNCg0KYGBge3J9DQoNCiMgbG9hZCBzcExTIGZpbGVzDQpkYXQgPC0gcmVhZC5jc3YoIi4uL2RhdGEvZGF0LkNWLmNzdiIsIGhlYWQgPSBUUlVFKQ0KDQojKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyMNCiMgRGlmZmVyZW5jZSBiZXR3ZWVuIGxhcmdlciBzcGVjaWVzIChzcEwpIGFuZCBoeWJyaWRzIA0KIysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysjDQoNCmZvciAoaSBpbiBjKCJzcEwiKSkgeyAjIGlkZW50aWZ5IHR5cGUgb2YgaHlicmlkcw0KICBmb3IgKGNyIGluIGMoImh5YkxTIiwgImh5YlNMIikpIHsgIyBpZGVudGlmeSB0eXBlIG9mIHBhcmVudGFscw0KICAgIGFzc2lnbigNCiAgICAgIHBhc3RlKGNyLCBpLCBzZXAgPSAiXyIpLA0KICAgICAgICBlc2NhbGMoDQogICAgICAgICAgbWVhc3VyZSA9ICJDVlIiLA0KICAgICAgICAgICMgTiBvZiBoeWJyaWRzDQogICAgICAgICAgbjFpID0gZGF0WywgcGFzdGUoIk4iLCBpLCBzZXAgPSAiLiIpXSwNCiAgICAgICAgICAjIE4gb2YgcGFyZW50YWxzDQogICAgICAgICAgbjJpID0gZGF0WywgcGFzdGUoIk4iLCBjciwgc2VwID0gIi4iKV0sDQogICAgICAgICAgIyBNZWFuIG9mIGh5YnJpZHMNCiAgICAgICAgICBtMWkgPSBkYXRbLCBwYXN0ZSgiTW4iLCBpLCBzZXAgPSAiLiIpXSwNCiAgICAgICAgICAjIE1lYW4gb2YgcGFyZW50YWxzDQogICAgICAgICAgbTJpID0gZGF0WywgcGFzdGUoIk1uIiwgY3IsIHNlcCA9ICIuIildLA0KICAgICAgICAgICMgU0Qgb2YgaHlicmlkcw0KICAgICAgICAgIHNkMWkgPSBkYXRbLCBwYXN0ZSgiU0QiLCBpLCBzZXAgPSAiLiIpXSwNCiAgICAgICAgICAjIFNEIG9mIHBhcmVudGFscw0KICAgICAgICAgIHNkMmkgPSBkYXRbLCBwYXN0ZSgiU0QiLCBjciwgc2VwID0gIi4iKV0sDQogICAgICAgICAgZGF0YSA9IGRhdA0KICAgICAgICAgICkgJT4lDQogICAgICAgICAgc2VsZWN0KEVTLklELCB5aSwgdmkpICU+JQ0KICAgICAgICAgIHJlbmFtZSgibG5DVlIuZXMiID0gInlpIiwgImxuQ1ZSLnN2IiA9ICJ2aSIpICU+JSANCiAgICAgIG11dGF0ZSgNCiAgICAgICAgIyBkaXJlY3Rpb24gb2YgdHJhbnNncmVzc3ZlIHNlZ3JlZ2F0aW9uIC0gZ3JlYXRlciB0aGFuIHBhcmVudA0KICAgICAgICBkaXJlY3Rpb24gPSAiKyIsDQogICAgICAgICMgU0UgZm9yIGxvZ2lzdGljIGRpc3RyaWJ1dGlvbiwgZm9yIHRoZSB3ZWlnaHRlZCBiaW5vbWlhbCByZWdyZXNzaW9uDQogICAgICAgICMgU0UgPSBwaS9zcXJ0KDMqKG5fZSArIG5fYykpDQogICAgICAgIFNFID0gcGkvc3FydCgzKigNCiAgICAgICAgICBkYXRbLCBwYXN0ZSgiTiIsIGksIHNlcCA9ICIuIildICsgZGF0WywgcGFzdGUoIk4iLCBjciwgc2VwID0gIi4iKV0NCiAgICAgICAgKSkNCiAgICAgICkNCiAgICApDQogIH0NCn0NCg0KIysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysjDQojIERpZmZlcmVuY2UgYmV0d2VlbiBoeWJyaWRzIGFuZCBzbWFsbGVyIHNwZWNpZXMgKHNwUykNCiMrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrIw0KDQpmb3IgKGkgaW4gYygiaHliTFMiLCAiaHliU0wiKSkgeyAjIGlkZW50aWZ5IHR5cGUgb2YgaHlicmlkcw0KICBmb3IgKGNyIGluIGMoInNwUyIpKSB7ICMgaWRlbnRpZnkgdHlwZSBvZiBwYXJlbnRhbHMNCiAgICBhc3NpZ24oDQogICAgICBwYXN0ZShpLCBjciwgc2VwID0gIl8iKSwNCiAgICAgICAgZXNjYWxjKA0KICAgICAgICAgIG1lYXN1cmUgPSAiQ1ZSIiwNCiAgICAgICAgICAjIE4gb2YgaHlicmlkcw0KICAgICAgICAgIG4xaSA9IGRhdFssIHBhc3RlKCJOIiwgaSwgc2VwID0gIi4iKV0sDQogICAgICAgICAgIyBOIG9mIHBhcmVudGFscw0KICAgICAgICAgIG4yaSA9IGRhdFssIHBhc3RlKCJOIiwgY3IsIHNlcCA9ICIuIildLA0KICAgICAgICAgICMgTWVhbiBvZiBoeWJyaWRzDQogICAgICAgICAgbTFpID0gZGF0WywgcGFzdGUoIk1uIiwgaSwgc2VwID0gIi4iKV0sDQogICAgICAgICAgIyBNZWFuIG9mIHBhcmVudGFscw0KICAgICAgICAgIG0yaSA9IGRhdFssIHBhc3RlKCJNbiIsIGNyLCBzZXAgPSAiLiIpXSwNCiAgICAgICAgICAjIFNEIG9mIGh5YnJpZHMNCiAgICAgICAgICBzZDFpID0gZGF0WywgcGFzdGUoIlNEIiwgaSwgc2VwID0gIi4iKV0sDQogICAgICAgICAgIyBTRCBvZiBwYXJlbnRhbHMNCiAgICAgICAgICBzZDJpID0gZGF0WywgcGFzdGUoIlNEIiwgY3IsIHNlcCA9ICIuIildLA0KICAgICAgICAgIGRhdGEgPSBkYXQNCiAgICAgICAgICApICU+JQ0KICAgICAgICAgIHNlbGVjdChFUy5JRCwgeWksIHZpKSAlPiUNCiAgICAgICAgICByZW5hbWUoImxuQ1ZSLmVzIiA9ICJ5aSIsICJsbkNWUi5zdiIgPSAidmkiKSAlPiUgDQogICAgICBtdXRhdGUoDQogICAgICAgICMgZGlyZWN0aW9uIG9mIHRyYW5zZ3Jlc3N2ZSBzZWdyZWdhdGlvbiAtIHNtYWxsZXIgdGhhbiBwYXJlbnQNCiAgICAgICAgZGlyZWN0aW9uID0gIi0iLA0KICAgICAgICAjIFNFIGZvciBsb2dpc3RpYyBkaXN0cmlidXRpb24sIGZvciB0aGUgd2VpZ2h0ZWQgYmlub21pYWwgcmVncmVzc2lvbg0KICAgICAgICAjIFNFID0gcGkvc3FydCgzKihuX2UgKyBuX2MpKQ0KICAgICAgICBTRSA9IHBpL3NxcnQoMyooDQogICAgICAgICAgZGF0WywgcGFzdGUoIk4iLCBpLCBzZXAgPSAiLiIpXSArIGRhdFssIHBhc3RlKCJOIiwgY3IsIHNlcCA9ICIuIildDQogICAgICAgICkpDQogICAgICApDQogICAgKQ0KICB9DQp9DQoNCg0KIysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysjDQojIERhdGEgb3V0cHV0DQojKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyMNCg0KYmluZF9yb3dzKA0KICAjIyBEaWZmZXJlbmNlIHdpdGggbW90aGVyIHNwZWNpZXMgIyMjDQogIGJpbmRfcm93cyhoeWJMU19zcEwsIGh5YlNMX3NwUykgJT4lDQogICAgbXV0YXRlKHBhcmVudGFsID0gIk1vdGhlciIpLA0KICAjIyBEaWZmZXJlbmNlIHdpdGggZmF0aGVyIHNwZWNpZXMgIyMjDQogIGJpbmRfcm93cyhoeWJMU19zcFMsIGh5YlNMX3NwTCkgJT4lDQogICAgbXV0YXRlKHBhcmVudGFsID0gIkZhdGhlciIpDQogICkgJT4lDQogIGRyb3BfbmEobG5DVlIuZXMpICU+JQ0KICBsZWZ0X2pvaW4oLiwgZGF0KSAlPiUNCiAgIyBBc3NpZ24gbm92ZWwgdmFyaWFiaWxpdHkgdG8gMSwgbm9uLW5vdmVsIHZhcmlhYmlsaXR5IHRvIDAgZm9yIGVhY2ggZWZmZWN0IHNpemUNCiAgbXV0YXRlKE5vdmVsdHkgPSBpZmVsc2UobG5DVlIuZXMgPCAwLCAxLCAwKSkgJT4lDQogICMjIEpvaW4gd2l0aCBtZXRhZGF0YSAjIyMNCiAgbGVmdF9qb2luKA0KICAgIC4sDQogICAgcmVhZC54bHN4KA0KICAgICAgIi4uL2RhdGEvb3JpZ2luYWwuZGF0YS54bHN4Iiwgc2hlZXQgPSAiU3BlY2llcy5sZXZlbC5tb2RlcmF0b3JzIg0KICAgICAgKQ0KICAgICkgJT4lDQogIG11dGF0ZV9hdCh2YXJzKGNvbnRhaW5zKCJkaXZlcmdlbmNlIikpLCBhcy5udW1lcmljKSAlPiUNCiAgbXV0YXRlX2F0KHZhcnMoY29udGFpbnMoImRpdmVyZ2VuY2UiKSksIHNjYWxlKSAlPiUNCiAgYXMuZGF0YS5mcmFtZSAlPiUNCiAgc2VsZWN0KC10cmFpdCkgJT4lDQogIGRyb3BfbmEoSGV0ZXJvLnNleCwgdHJhaXQudHlwZSwgR2VuZXQuZGl2ZXJnZW5jZSkgJT4lDQogICMgb3JkZXIgdGF4b24NCiAgd2l0aGluKA0KICAgIHRheGEgPC0gb3JkZXJlZCgNCiAgICAgIHRheGEsDQogICAgICBsZXZlbHMgPSBjKCJOZXVyb3B0ZXJhIiwgIkNvbGVvcHRlcmEiLCAiRGlwdGVyYSIsICJMZXBpZG9wdGVyYSIsICJPcnRob3B0ZXJhIiwgIkF2ZXMiLCAiUm9kZW50aWEiLCAiQW51cmEiLCAiQ2ljaGxpZm9ybWVzIikNCiAgICAgICkNCiAgICApICU+JQ0KICBtdXRhdGVfaWYoaXMuY2hhcmFjdGVyLCBhcy5mYWN0b3IpICU+JQ0KICAjIEluc2VjdCBvciBubw0KICBtdXRhdGUoDQogICAgaW5zZWN0ID0gaWZlbHNlKHRheGEgJWluJSBjKCJBdmVzIiwgIlJvZGVudGlhIiwgIkFudXJhIiwgIkNpY2hsaWZvcm1lcyIpLCAibm8iLCAiaW5zZWN0IiksDQogICkgJT4lDQogIHdyaXRlLmNzdigiLi4vZGF0YS92YXJpYXRpb24uRVMuTm92ZWx0eS5jc3YiLCByb3cubmFtZXMgPSBGKQ0KDQpgYGANCg0KDQojIyBSZWxvYWQgZGF0YSAmIFByZXBhcmUgcGh5bG9nZW5ldGljIHRyZWUNCg0KYGBge3IsIGZpZy5oZWlnaHQgPSA2LjUsIGZpZy5jYXAgPSAiRmlndXJlIFMyLiBQaHlsb2dlbmV0aWMgdHJlZSB1c2VkIGluIG1ldGEtYW5hbHlzaXMgZm9yIHBoZW5vdHlwaWMgdmFyaWFiaWxpdHkgKGNvZWZmaWNpZW50IG9mIHZhcmlhdGlvbiwgQ1YpLCB3aGljaCB3YXMgYmFzZWQgb24gdHJlZSBvZiB0aGUgcGFyZW50YWwgc3BlY2llcyB3aXRoIGxhcmdlciBDViBpbiB0cmFpdCBzaXplIn0NCg0KIyBMb2FkIGVmZmVjdCBzaXplcw0KdmFyLmRpZiA8LSByZWFkLmNzdigiLi4vZGF0YS92YXJpYXRpb24uRVMuZ2VuZXJhbC5jc3YiLCBoZWFkID0gVFJVRSklPiUNCiAgIyBpbmRpY2F0ZSBkYXRhc2V0IGluY2x1ZGluZyBub3ZlbCB2YXJpYWJpbGl0eQ0KICBtdXRhdGUoZGF0YS50eXBlID0gIkFsbHRyYWl0cyIpDQoNCiMgT2JzZXJ2YXRpb25zIHdpdGggbm92ZWwgdmFyaWFiaWxpdHkNCkFsbCA8LSByZWFkLmNzdigiLi4vZGF0YS92YXJpYXRpb24uRVMubm92ZWx0eS5jc3YiLCBoZWFkID0gVFJVRSkgJT4lDQogIGZpbHRlcihsbkNWUi5lcyA8IDApICU+JQ0KICBkaXN0aW5jdChFUy5JRCkNCiMgRWZmZWN0IHNpemVzIHdpdGggbm9uLW5vdmVsIHZhcmlhYmlsaXR5DQpOb25vdmVsIDwtIHJlYWQuY3N2KCIuLi9kYXRhL3ZhcmlhdGlvbi5FUy5nZW5lcmFsLmNzdiIsIGhlYWQgPSBUUlVFKSAlPiUNCiAgZmlsdGVyKCFFUy5JRCAlaW4lIHVuaXF1ZShBbGwkRVMuSUQpKSAlPiUNCiAgIyBpbmRpY2F0ZSBkYXRhc2V0IHdpdGhvdXQgbm92ZWwgdmFyaWFiaWxpdHkNCiAgbXV0YXRlKGRhdGEudHlwZSA9ICJOb25ub3ZlbHRyYWl0cyIpDQoNCiMgY29tYmluZSBkYXRhc2V0IHdpdGgvd2l0aG91dCBub3ZlbCB2YXJpYWJpbGl0eQ0KTm92ZWwuTm9ubm92ZWwgPC0gYmluZF9yb3dzKHZhci5kaWYsIE5vbm92ZWwpICU+JQ0KICBtdXRhdGUobWV0YXVuaXQgPSAgc3RyX2MoZGF0YS50eXBlLCBjcm9zcywgc2VwID0gIl8iKSkgJT4lDQogICMgVXNlIG9ic2VydmF0aW9ucyB3aXRoIGJvdGggcmVjaXByb2NhbCBjcm9zc2VzDQogIGRyb3BfbmEoY29udGFpbnMoIk1uIiksIGNvbnRhaW5zKCJTRCIpKSAlPiUNCiAgIyBJbnNlY3Qgb3Igbm8NCiAgbXV0YXRlKA0KICAgIGluc2VjdCA9IGlmZWxzZSh0YXhhICVpbiUgYygiQ2ljaGxpZm9ybWVzIiwgIkFudXJhIiwgIkF2ZXMiLCAiUm9kZW50aWEiKSwgIm5vIiwgImluc2VjdCIpLA0KICApDQoNCiMrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrIw0KIyBQaHlsb2dlbnkgDQojKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyMNCg0KIyAjIG1hdGNoaW5nIG5hbWVzIGZyb20gb3BlbiB0cmVlIHRheG9ub215DQojIHRheGEgPC0gdG5yc19tYXRjaF9uYW1lcygNCiMgICBuYW1lcyA9IGxldmVscyh2YXIuZGlmJHNwTC5uYW1lKSAlPiUNCiMgICAgIHN0cl9yZXBsYWNlX2FsbCgiXyIsICIgIiksIA0KIyAgIGNvbnRleHRfbmFtZSA9ICJBbmltYWxzIg0KIyAgICkNCiMgDQojICMgQ3JlYXRlIHRyZWUNCiMgdHJlZSA8LSB0b2xfaW5kdWNlZF9zdWJ0cmVlKG90dF9pZHMgPSB0YXhhJG90dF9pZCkNCiMgdHJlZSR0aXAubGFiZWwgJTw+JQ0KIyAgIHN0cmlwX290dF9pZHMgIyByZW1vdmUgT1RUIElEcyBmcm9tIHRpcCBsYWJlbHMNCiMgIyByYW5kb21seSBzb2x2ZSBub24tYmluYXJ5IHBoeWxvZ2VueQ0KIyBzZXQuc2VlZCg2KQ0KIyBiaW4udHJlZSA8LSBtdWx0aTJkaSh0cmVlLCByYW5kb20gPSBUKQ0KIyANCiMgIyBGaXggbmFtZXMgb2YgdGlwIGxhYmVscw0KIyBiaW4udHJlZSR0aXAubGFiZWwgJTw+JSBzdHJfcmVwbGFjZV9hbGwoIkRyeW9waHl0ZXMiLCAiSHlsYSIpDQojICMgSW5kaWNhdGUgbWlzbWF0Y2ggYmV0d2VlbiB0aXAgbGFiZWxzICYgZGF0YXNldCBzcGVjaWVzIG5hbWVzDQojIHNldGRpZmYobGV2ZWxzKGFzLmZhY3RvcihiaW4udHJlZSR0aXAubGFiZWwpKSwgbGV2ZWxzKHZhci5kaWYkc3BMLm5hbWUpKQ0KIyBzZXRkaWZmKGxldmVscyh2YXIuZGlmJHNwTC5uYW1lKSwgbGV2ZWxzKGFzLmZhY3RvcihiaW4udHJlZSR0aXAubGFiZWwpKSkNCg0KIyB3cml0ZS50cmVlKGJpbi50cmVlLCBmaWxlPSAiLi4vZGF0YS9waHlsby52YXJpYXRpb24udHJlIikNCg0KIyBjb21wdXRlIGJyYW5jaCBsZW5ndGhzIG9mIHRyZWUNCnBoeWxvX2JyYW5jaCA8LSByZWFkLnRyZWUoZmlsZSA9ICIuLi9kYXRhL3BoeWxvLnZhcmlhdGlvbi50cmUiKSAlPiUNCiAgY29tcHV0ZS5icmxlbihiaW4udHJlZSwgbWV0aG9kID0gIkdyYWZlbiIsIHBvd2VyID0gMSkNCg0KIyBzYXZpbmcgcGh5bG9nZW5laWMgbWF0cml4DQpwaHlsb19jb3IgPC0gdmN2KHBoeWxvX2JyYW5jaCwgY29yID0gVCkNCg0KIyBOb3RlIG9uZSBvZiB0aGUgdGlwcyBpcyBjYWxsZWQgIkxhdGVzIGNhbGNhcmlmZXIgKGVzdGltYXRlZCkiDQpwaHlsb19icmFuY2gkbm9kZS5sYWJlbCA8LSBOVUxMDQoNCiMgUGxvdCB0cmVlDQpwbG90LnBoeWxvKHBoeWxvX2JyYW5jaCwgY2V4ID0gMC43KQ0KDQpgYGANCjxicj4NCg0KPGRpdiBzdHlsZT0ibWFyZ2luLWJvdHRvbTo3MHB4OyI+DQo8L2Rpdj4NCg0KIyMgRG9taW5hbmNlIGluIGNvZWZmaWNpZW50IG9mIHZhcmlhdGlvbiAoQ1YpDQoNCldlIGNvbXBhcmVkIG1pZHBhcmVudC12YWx1ZSBvZiBwaGVub3R5cGljIHZhcmlhYmlsaXR5IChDVikgYW5kIGh5YnJpZHMnIHBoZW5vdHlwaWMgdmFyaWFiaWxpdHkgYnkgY2FsY3VsYXRpbmcgbG9nIHJhdGlvIG9mIHBoZW5vdHlwaWMgdmFyaWFiaWxpdHkgKGxuQ1ZSKSBvZiBtaWRwYXJlbnQtdmFsdWUgYW5kIGh5YnJpZHMgdG8gPGk+c3BTUzxzdWI+Vjwvc3ViPjwvaT4uIDxicj4gDQoNCmxuQ1ZSIG9mIG1pZHBhcmVudC12YWx1ZSB0byA8aT5zcFNTPHN1Yj5WPC9zdWI+PC9pPiB3YXMsIGZvbGxvd2luZyAkbG5DVlI9XGxue1xmcmFje0NWX0V9e0NWX0N9fStcZnJhY3sxfXsyKE5fRS0xKX0tXGZyYWN7MX17MihOX0MtMSl9JCANCiwgY2FsY3VsYXRlZCBhcyA8YnI+DQokJFxsblxmcmFje0NWX3tzcExMX1Z9K0NWX3tzcFNTX1Z9fXsyfS1cbG57Q1Zfe3NwU1NfVn19ICsgIFxmcmFjezF9e05fe3NwTExfVn0rTl97c3BTU19WfS0yfS1cZnJhY3sxfXsyKE5fe3NwU1NfVn0gLSAxKX0kJA0KSXQncyBzYW1wbGluZyB2YXJpYW5jZSB3YXMgc3Vic3RpdHV0ZSBieSB0aGF0IG9mIDxpPnNwTEw8c3ViPlY8L3N1Yj48L2k+IDxicj4NCg0KV2Ugc3RhdGlzdGljYWxseSBjb21wYXJlZCB0aG9zZSBlZmZlY3Qgc2l6ZXMgdGhyb3VnaCB0aGUgZm9ybWFsIG1ldGEtcmVncmVzc2lvbiBieSB1c2luZyBgcm1hLm12YCBmdW5jdGlvbiBvZiBSIHBhY2thZ2UgYG1ldGFmb3JgIDxicj4NCg0KQWxsIG1ldGEtYW5hbHl0aWMgbW9kZWxzIGluY2x1ZGVkIGZvbGxvd2luZyBSYW5kb20gZWZmZWN0cyBlc3RpbWF0ZXM6IA0KDQoqIGBTdHVkeS5JRGA6IFByaW1hcnkgc3R1ZGllcy4gRGVub3RlZCBhcyAqKlN0dWR5KioNCg0KKiBgQ3Jvc3MuSURgOiBQYXJlbnRhbCBzdHJhaW4gdXNlZCBpbiB0aGUgY3Jvc3NpbmcuIERpc2NyaW1pbmF0ZSBpbnRyYXNwZWNpZmljIHBvcHVsYXRpb25zLiBEZW5vdGVkIGFzICoqY3Jvc3NlZCBzdHJhaW4qKg0KDQoqIGBzcEwubmFtZWA6IFBoeWxvZ2VueSBvZiBwYXJlbnRhbCBzcGVjaWVzICg8aT5zcExMPHN1Yj5NPC9zdWI+PC9pPikuIERlbm90ZWQgYXMgKipzcGVjaWVzIHdpdGggcGh5bG9nZW55KioNCg0KYGBge3J9DQoNCiMrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrIw0KIyBDYWxjdWxhdGUgbWlkcGFyZW50IA0KIysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysjDQptaWRwYXJlbnQgPC0gTm92ZWwuTm9ubm92ZWwgJT4lDQogICMgRGl2aWRlIG1lYW4gYnkgMiBpbiBzcEwgd2hlcmVhcyBoeWJyaWRzIGFyZSBjb25zdGFudA0KICAgbXV0YXRlKA0KICAgICBDVi5zcEwgPSBTRC5zcEwvTW4uc3BMLA0KICAgICBDVi5zcFMgPSBTRC5zcFMvTW4uc3BTDQogICAgICkgJT4lDQogICBtdXRhdGUoDQogICAgIGxuQ1ZSLm1pZHBhcmVudC5lcyA9DQogICAgICAgaWZlbHNlKA0KICAgICAgICAgY3Jvc3MgPT0gInNwTCIsDQogICAgICAgICAjIGxvZyhDVmUvQ1ZjKQ0KICAgICAgICAgbG9nKChDVi5zcEwgKyBDVi5zcFMpLzIpIC0gbG9nKENWLnNwUykgKyAgDQogICAgICAgICAgICMgMS8yKE5lLTEpIC0gMS8yKE5jLTEpDQogICAgICAgICAgIDEvKE4uc3BMICsgTi5zcFMgLTIpIC0gMS8oMipOLnNwUyAtIDIpLCANCiAgICAgICAgIGxuQ1ZSLmVzDQogICAgICAgICApDQogICAgICMgRGl2aWRlIHZhcmlhbmNlIGJ5IDQgaW4gc3BMIHdoZXJlYXMgaHlicmlkcyBhcmUgY29uc3RhbnQNCiAgICAgKSAlPiUNCiAgIG11dGF0ZV9hdCgiY3Jvc3MiLCBhcy5mYWN0b3IpICU+JQ0KICAgd2l0aGluKGxldmVscyhjcm9zcykgPC0gYygiaHliTFMiLCAiaHliU0wiLCAibWlkcGFyZW50IikpDQoNCg0KIysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyMNCiMgQ29tcGFyZSBtaWRwYXJlbnQgYW5kIGh5YnJpZHMgYnkgbWV0YS1yZWdyZXNzb24NCiMrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysjDQoNCmZvciAodHIgaW4gYygiQWxsdHJhaXRzIiwgIk5vbm5vdmVsdHJhaXRzIikpIHsNCiAgZm9yICh0YXhvbiBpbiBjKCJhbGx0YXhvbiIsICJpbnNlY3QiKSkgew0KICAgIA0KICAgICMgRmlsdGVyaW5nIHRheG9uIChhbGwgdGF4b24gb3IgaW5zZWN0cykNCiAgICBpZiAodGF4b24gPT0gImFsbHRheG9uIikgew0KICAgICAgZGF0IDwtIG1pZHBhcmVudCAlPiUgDQogICAgICAgIGZpbHRlcihkYXRhLnR5cGUgPT0gdHIpDQogICAgfSBlbHNlIHsNCiAgICAgIGRhdCA8LSBtaWRwYXJlbnQgJT4lIA0KICAgICAgICBmaWx0ZXIoZGF0YS50eXBlID09IHRyLCBpbnNlY3QgPT0gdGF4b24pDQogICAgfQ0KDQogICAgIyAjKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysjDQogICAgIyAjIEVzdGltYXRlIG1ldGEtYW5hbHl0aWMgbWVhbiBvZiBtaWRwYXJlbnQgb2YgcGhlbm90eXBpYyB2YXJpYXRpb24NCiAgICAjICMrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyMNCiAgICAjIG1pZHBhcmVudC5jb21wYXJlIDwtIHJtYS5tdigNCiAgICAjICAgeWkgPSBsbkNWUi5taWRwYXJlbnQuZXMsIFYgPSBsbkNWUi5zdiwNCiAgICAjICAgZGF0YSA9IGRhdCwNCiAgICAjICAgbWV0aG9kID0gIlJFTUwiLA0KICAgICMgICByYW5kb20gPSBsaXN0KH4xIHwgc3BMLm5hbWUsIH4xIHwgU3R1ZHkuSUQsIH4xIHwgQ3Jvc3MuSUQsIH4xIHwgRVMuSUQpLA0KICAgICMgICBSID0gbGlzdChzcEwubmFtZSA9IHBoeWxvX2NvciksDQogICAgIyAgIG1vZHMgPSB+IHJlbGV2ZWwoY3Jvc3MsIHJlZiA9ICJtaWRwYXJlbnQiKQ0KICAgICMgICApDQogICAgIyAjIyBTYXZlIG1vZGVsICMjIw0KICAgICMgc2F2ZVJEUygNCiAgICAjICAgbWlkcGFyZW50LmNvbXBhcmUsDQogICAgIyAgIGZpbGUgPSBwYXN0ZSgiLi4vQW5hbHlzaXMvVmFyaWF0aW9uLm1pZHBhcmVudC5jb21wYXJlIiwgdHIsIHRheG9uLCAib2JqIiwgc2VwID0gIi4iKQ0KICAgICMgICApDQogIA0KICAgICMjIExvYWQgbW9kZWwgIyMjDQogICAgbWlkcGFyZW50LmNvbXBhcmUgPC0gcmVhZFJEUyhwYXN0ZSgiLi4vQW5hbHlzaXMvVmFyaWF0aW9uLm1pZHBhcmVudC5jb21wYXJlIiwgdHIsIHRheG9uLCAib2JqIiwgc2VwID0gIi4iKSkNCiAgICANCiAgICBhc3NpZ24oDQogICAgICBwYXN0ZSgiRG9taW5hbmNlIiwgdHIsIHRheG9uLCBzZXAgPSAiLiIpLA0KICAgICAgZ2V0X3JlZyhtaWRwYXJlbnQuY29tcGFyZSkgJT4lDQogICAgICAgICMgU2hvdyBkYXRhc2V0IG5hbWUNCiAgICAgICAgd2l0aGluKERhdGFzZXQgPC0gYyhwYXN0ZSh0ciwgdGF4b24pLCByZXAoIiIsIGxlbmd0aCguJEVzdGltYXRlKS0xKSkpICU+JQ0KICAgICAgICAjIFJlbmFtZSBmaXhlZCBlZmZlY3RzDQogICAgICAgIHdpdGhpbignRml4ZWQgZWZmZWN0cycgPC0gYygiIiwgIm1pZHBhcmVudCAoaW50cmNwdCkiLCAiaHliTFMiLCAiaHliU0wiKSkgJT4lDQogICAgICAgICMgRGlmZmVyZW5jZSBvZiBlYWNoIGNyb3NzIGZyb20gbWlkcGFyZW50IGluICUNCiAgICAgICAgbXV0YXRlKCdDb21wYXJpc29uIHdpdGggbWlkcGFyZW50JyA9IGMoDQogICAgICAgICAgcmVwKCIiLCAyKSwNCiAgICAgICAgICAjIERpZmZlcmVuY2UgaHliTFMgLSBtaWRwYXJlbnQNCiAgICAgICAgICBwYXN0ZSgNCiAgICAgICAgICAgIHJvdW5kKA0KICAgICAgICAgICAgMTAwKihleHAobWlkcGFyZW50LmNvbXBhcmUkYmV0YVsxXSttaWRwYXJlbnQuY29tcGFyZSRiZXRhWzJdKSAgICAgICAgICAgIC1leHAobWlkcGFyZW50LmNvbXBhcmUkYmV0YVsxXSkpLCAjIGh5YnJpZCBMUw0KICAgICAgICAgICAgMiksDQogICAgICAgICAgICAiJSBsYXJnZXIiDQogICAgICAgICAgICApLA0KICAgICAgICAgICAgICAjIGJldGFbMV0gOiBtaWRwYXJlbnQNCiAgICAgICAgICAgICAgIyBiZXRhWzJdIDogaHliTFMNCiAgICAgICAgICAgICAgIyBiZXRhWzNdIDogaHliU0wNCiAgICAgICAgICAjIERpZmZlcmVuY2UgaHliU0wgLSBtaWRwYXJlbnQNCiAgICAgICAgICBwYXN0ZSgNCiAgICAgICAgICAgIHJvdW5kKA0KICAgICAgICAgICAgMTAwKihleHAobWlkcGFyZW50LmNvbXBhcmUkYmV0YVsxXSttaWRwYXJlbnQuY29tcGFyZSRiZXRhWzNdKS1leHAobWlkcGFyZW50LmNvbXBhcmUkYmV0YVsxXSkpLCAjIGh5YnJpZCBTTA0KICAgICAgICAgICAgMiksDQogICAgICAgICAgICAiJSBsYXJnZXIiDQogICAgICAgICAgICApDQogICAgICAgICAgKSkNCiAgICAgICkNCg0KICAgICMgIysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysjDQogICAgIyAjIE1ldGEtYW5hbHlzaXMgZm9yIG1pZHBhcmVudCB0byBwbG90IGJhbmQNCiAgICAjICMrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrIw0KICAgICMgDQogICAgIyAjIFBoeWxvZ2VuZXRpYyByYW5kb20gbWV0YS1hbmFseXNpcw0KICAgICMgbWlkcGFyZW50LnJhbmRvbSA8LSBybWEubXYoDQogICAgIyAgIHlpID0gbG5DVlIubWlkcGFyZW50LmVzLA0KICAgICMgICBWID0gbG5DVlIuc3YsDQogICAgIyAgIGRhdGEgPSBkYXQgJT4lDQogICAgIyAgICAgZmlsdGVyKGNyb3NzID09ICJtaWRwYXJlbnQiKSwNCiAgICAjICAgbWV0aG9kID0gIlJFTUwiLA0KICAgICMgICByYW5kb20gPSBsaXN0KH4xIHwgc3BMLm5hbWUsIH4xIHwgU3R1ZHkuSUQsIH4xIHwgQ3Jvc3MuSUQsIH4xIHwgRVMuSUQpLA0KICAgICMgICBSID0gbGlzdChzcEwubmFtZSA9IHBoeWxvX2NvcikNCiAgICAjICAgKQ0KICAgICMgIyMgU2F2ZSBtb2RlbCAjIyMNCiAgICAjIHNhdmVSRFMoDQogICAgIyAgIG1pZHBhcmVudC5yYW5kb20sDQogICAgIyAgIGZpbGUgPSBwYXN0ZSgiLi4vQW5hbHlzaXMvVmFyaWF0aW9uLm1pZHBhcmVudCIsIHRyLCB0YXhvbiwgIm9iaiIsIHNlcCA9ICIuIikNCiAgICAjICAgKQ0KICAgIA0KICB9DQp9DQoNCmJpbmRfcm93cygNCiAgRG9taW5hbmNlLkFsbHRyYWl0cy5hbGx0YXhvbiwgRG9taW5hbmNlLk5vbm5vdmVsdHJhaXRzLmFsbHRheG9uLA0KICBEb21pbmFuY2UuQWxsdHJhaXRzLmluc2VjdCwgRG9taW5hbmNlLk5vbm5vdmVsdHJhaXRzLmluc2VjdA0KICApICU+JQ0KICBrYWJsZSgiaHRtbCIsIGRpZ2l0cyA9IDMsIGNhcHRpb24gPSAiVGFibGUgUzUuIFJlc3VsdHMgb2YgbWV0YS1hbmFseXNpcyBpbnZlc3RpZ2F0aW5nIGRvbWluYW5jZSBpbiBwaGVub3R5cGljIHZhcmlhYmlsaXRpZXMgdXNpbmcgZnVsbCBkYXRhc2V0IG9yIGRhdGEgc3Vic2V0cyIpICU+JQ0KICBrYWJsZV9zdHlsaW5nKCJzdHJpcGVkIiwgcG9zaXRpb24gPSAibGVmdCIpICU+JQ0KICBzY3JvbGxfYm94KHdpZHRoID0gIjEwMCUiLCBoZWlnaHQgPSAiNTAwcHgiKQ0KDQpgYGANCg0KDQo8ZGl2IHN0eWxlPSJtYXJnaW4tYm90dG9tOjcwcHg7Ij4NCjwvZGl2Pg0KDQojIyBVbml2YXJhdGUgbWV0YS1hbmFseXNpcyBmb3IgZWFjaCBjcm9zcyAodXNpbmcgQ1YpDQpRdWFudGlmeSBhbmQgdmlzdWFsaXNlIG92ZXJhbGwgdHJlbmQgb2YgcGhlbm90eXBpYyB2YXJpYWJpbGl0eSAoQ1YpIG9mIGh5YnJpZHMgY29tcGFyZWQgdG8gcGFyZW50cyA8YnI+DQpNZXRhLWFuYWx5c2lzIHdhcyByZXBlYXRlZCBmb3Igc3Vic2V0IGRhdGEgLSBpbmNsdWRpbmcgb25seSBub24tbm92ZWwgcGhlbm90eXBlcywgb25seSBpbnNlY3RzLCBhbmQgbm9uLW5vdmVsIHBoZW5vdHlwZXMgaW4gaW5zZWN0cyA8YnI+DQpNZXRhLWFuYWx5c2lzIHdhcyBjb25kdWN0ZWQgYnkgdXNpbmcgYHJtYS5tdmAgZnVuY3Rpb24gaW4gYG1ldGFmb3JgIHBhY2thZ2UgPGJyPg0KDQoqIENvbmZpZGVudGlhbCBpbnRlcnZhbCA6IHRoaWNrIGxpbmUgIA0KDQoqIFByZWRpY3Rpb24gaW50ZXJ2YWwgOiB0aGluIGxpbmUNCg0KYGBge3IsIGZpZy5oZWlnaHQgPSA0LCBmaWcud2lkdGggPSA2fQ0KDQpmb3IgKHRyIGluIGMoIkFsbHRyYWl0cyIsICJOb25ub3ZlbHRyYWl0cyIpKSB7DQogIGZvciAodGF4b24gaW4gYygiYWxsdGF4b24iLCAiaW5zZWN0IikpIHsNCg0KICAgIGlmICh0YXhvbiA9PSAiYWxsdGF4b24iKSB7DQogICAgICBkYXQgPC0gTm92ZWwuTm9ubm92ZWwgJT4lDQogICAgICAgIGZpbHRlcihjcm9zcyA9PSBjciwgZGF0YS50eXBlID09IHRyKQ0KICAgIH0gZWxzZSB7DQogICAgICBkYXQgPC0gTm92ZWwuTm9ubm92ZWwgJT4lDQogICAgICAgIGZpbHRlcihjcm9zcyA9PSBjciwgZGF0YS50eXBlID09IHRyLCBpbnNlY3QgPT0gdGF4b24pDQogICAgfQ0KICAgIA0KICAgIHJlcy5tYSA8LSBmb3JlYWNoKA0KICAgICAgY3IgPSBjKCJzcEwiLCAiaHliTFMiLCAiaHliU0wiKSwgLmNvbWJpbmUgPSBgcmJpbmRgDQogICAgICApICVkbyUgew0KICAgICAgIyAjIFBoeWxvZ2VuZXRpYyByYW5kb20gbWV0YS1hbmFseXNpcw0KICAgICAgIyBwaHlsLnJhbmRvbSA8LSBybWEubXYoDQogICAgICAjICAgeWkgPSBsbkNWUi5lcywgViA9IGxuQ1ZSLnN2LA0KICAgICAgIyAgIGRhdGEgPSBkYXQsIG1ldGhvZCA9ICJSRU1MIiwNCiAgICAgICMgICByYW5kb20gPSBsaXN0KH4xIHwgc3BMLm5hbWUsIH4xIHwgU3R1ZHkuSUQsIH4xIHwgQ3Jvc3MuSUQsIH4xIHwgRVMuSUQpLA0KICAgICAgIyAgIFIgPSBsaXN0KHNwTC5uYW1lID0gcGh5bG9fY29yKQ0KICAgICAgIyAgICkNCiAgICAgICMgc2F2ZVJEUyhwaHlsLnJhbmRvbSwNCiAgICAgICMgICBmaWxlID0gcGFzdGUoIi4uL0FuYWx5c2lzL1ZhcmlhdGlvbi5tZXRhIiwgdHIsIHRheG9uLCBjciwgIm9iaiIsIHNlcCA9ICIuIikpDQoNCiAgICAgICMgY3JlYXRpbmcgc3VtbWFyeSB0YWJsZSBvZiByZXN1bHRzDQogICAgICByZWFkUkRTKA0KICAgICAgICBwYXN0ZSgiLi4vQW5hbHlzaXMvVmFyaWF0aW9uLm1ldGEiLCB0ciwgdGF4b24sIGNyLCAib2JqIiwgc2VwID0gIi4iKQ0KICAgICAgICApICU+JQ0KICAgICAgICAgIGdldF9wcmVkKCkgJT4lDQogICAgICAgICAgYXMuZGF0YS5mcmFtZSgpICU+JQ0KICAgICAgICAgIG11dGF0ZSgNCiAgICAgICAgICAgIE4gPSBsZW5ndGgoZGF0JEVTLklEKSwNCiAgICAgICAgICAgICMgSTIgPSBJMihwaHlsLnJhbmRvbSlbIkkyX3RvdGFsIl0gJT4lIHJvdW5kKDMpLA0KICAgICAgICAgICAgY3Jvc3MgPSBjciAjIGluZGljYXRlIGNyb3NzIChzcEwsIGh5YkxTLCBoeWJTTCkNCiAgICAgICAgICAgICkgJT4lIA0KICAgICAgICBhcy5kYXRhLmZyYW1lKCkgJT4lDQogICAgICAgIHdpdGhpbignRGF0YXNldCcgPC0gYyhwYXN0ZSh0ciwgdGF4b24pLCAiIiwgIiIpKSAlPiUgICMgZGF0YXNldCBuYW1lIGluIGZpcnN0IHJvdw0KICAgICAgICByZXR1cm4oKQ0KICAgICAgICB9DQoNCiAgICBpZiAodGF4b24gPT0gImFsbHRheG9uIikgew0KICAgICAgZGF0LnBsb3QgPC0gTm92ZWwuTm9ubm92ZWwgJT4lIA0KICAgICAgICBmaWx0ZXIoZGF0YS50eXBlID09IHRyKQ0KICAgIH0gZWxzZSB7DQogICAgICBkYXQucGxvdCA8LSBOb3ZlbC5Ob25ub3ZlbCAlPiUgDQogICAgICAgIGZpbHRlcihkYXRhLnR5cGUgPT0gdHIsIGluc2VjdCA9PSB0YXhvbikNCiAgICB9DQogICAgDQogICAgIyBCaW5kIHJlc3VsdCBvZiBhbGwgY3Jvc3NlcyBhdCBlYWNoIGRhdGFzZXQNCiAgICBhc3NpZ24oDQogICAgICBwYXN0ZSgicmVzLm1hIiwgdHIsIHRheG9uLCBzZXAgPSAiLiIpLA0KICAgICAgcmVzLm1hDQogICAgKQ0KICAgIA0KICAgICMjIE1pZHBhcmVudCBlc3RpbWF0ZSAmIENJICMjIw0KICAgIG1pZHBhcmVudC5tYS4yIDwtIHJlYWRSRFMoDQogICAgICBwYXN0ZSgiLi4vQW5hbHlzaXMvVmFyaWF0aW9uLm1pZHBhcmVudCIsIHRyLCB0YXhvbiwgIm9iaiIsIHNlcCA9ICIuIikNCiAgICAgICkgJT4lIA0KICAgICAgIyBQcmVkaWN0aW9uIGludGVydmFsIG9mIG1pZHBhcmVudA0KICAgICAgZ2V0X3ByZWQoKSAlPiUNCiAgICAgIGFzLmRhdGEuZnJhbWUoKQ0KICAgIA0KICAgICMgY3JlYXRpbmcgYSBmb3Jlc3QgcGxvdA0KICAgIHBsb3QubWV0YW1lYW4gPC0gZ2dwbG90KA0KICAgICAgZGF0YSA9IHJlcy5tYSwNCiAgICAgIGFlcyh4ID0gdGFuaChFc3RpbWF0ZSksIHkgPSBjcm9zcykNCiAgICAgICkgKw0KICAgICAgc2NhbGVfeV9kaXNjcmV0ZShleHBhbmQgPSBjKDAsMSkpICsNCiAgICAgIHNjYWxlX3hfY29udGludW91cygNCiAgICAgICAgbGltaXRzID0gYygtMSwgMSksDQogICAgICAgIGJyZWFrcyA9IHNlcSgtMSwgMSwgYnkgPSAwLjUpDQogICAgICAgICkgKw0KICAgICAgIyMgTWlkcGFyZW50IENJICMjIw0KICAgICAgZ2VvbV9yZWN0KA0KICAgICAgICBhZXMoDQogICAgICAgICAgeG1pbiA9IHRhbmgobWlkcGFyZW50Lm1hLjIkTG93ZXJDSSksDQogICAgICAgICAgeG1heCA9IHRhbmgobWlkcGFyZW50Lm1hLjIkVXBwZXJDSSksDQogICAgICAgICAgeW1pbiA9IC1JbmYsIHltYXggPSBJbmYNCiAgICAgICAgICApLA0KICAgICAgICBmaWxsPSJHcmV5IDk1IiwgaW5oZXJpdC5hZXMgPSBGQUxTRQ0KICAgICAgICApICsNCiAgICAgICMjIE1pZHBhcmVudCBlc3RpbWF0ZSAjIyMNCiAgICAgIGdlb21fdmxpbmUoDQogICAgICAgIHhpbnRlcmNlcHQgPSB0YW5oKG1pZHBhcmVudC5tYS4yJEVzdGltYXRlKSwgY29sb3VyID0gImdyZXkyMCIsDQogICAgICAgIGFscGhhID0gMC4zLCBzaXplID0gMQ0KICAgICAgICApICsNCiAgICAgICMjIE9yY2hhcmQgcGxvdCAjIyMNCiAgICAgIGdlb21fcXVhc2lyYW5kb20oDQogICAgICAgIGRhdGEgPSBkYXQucGxvdCAlPiUNCiAgICAgICAgICBmaWx0ZXIoZGF0YS50eXBlID09IHRyKSwNCiAgICAgICAgYWVzKHggPSB0YW5oKGxuQ1ZSLmVzKSwgeSA9IGNyb3NzLCBzaXplID0gMS9sbkNWUi5zdiwgY29sb3IgPSBjcm9zcyksDQogICAgICAgIGFscGhhID0gMC4yLCBHcm91cE9uWCA9IEZBTFNFDQogICAgICAgICkgKw0KICAgICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoIiNEQzI2N0YiLCAiIzc4NUVGMCIsICIjRkU2MTAwIikpICsNCiAgICAgICMgRGVsZXRlIGxlZ2VuZCBmb3IgY29sb3JzDQogICAgICBndWlkZXMoZmlsbCA9ICJub25lIiwgY29sb3VyID0gIm5vbmUiKSArDQogICAgICAjIyBDb25maWRlbnRpYWwgaW50ZXJ2YWwgIyMjDQogICAgICBnZW9tX2Vycm9yYmFyaCgNCiAgICAgICAgYWVzKHhtaW4gPSB0YW5oKExvd2VyQ0kpLCB4bWF4ID0gdGFuaChVcHBlckNJKSksDQogICAgICAgIGhlaWdodCA9IDAsIHNpemUgPSAxLjIsIGFscGhhID0gMC42DQogICAgICAgICkgKw0KICAgICAgIyMgUHJlZGljdGlvbiBpbnRlcnZhbCAjIyMNCiAgICAgIGdlb21fZXJyb3JiYXJoKA0KICAgICAgICBhZXMoeG1pbiA9IHRhbmgobG93ZXJQUiksIHhtYXggPSB0YW5oKHVwcGVyUFIpKSwNCiAgICAgICAgaGVpZ2h0ID0gMC4xLCBzaXplID0gMC41LCBhbHBoYSA9IDAuNg0KICAgICAgICApICsNCiAgICAgIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsIGxpbmV0eXBlID0gMiwgY29sb3VyID0gImJsYWNrIiwgYWxwaGEgPSAwLjMpICsNCiAgICAgICMjIEVzdGltYXRlICMjIw0KICAgICAgZ2VvbV9wb2ludChzaXplID0gMywgc2hhcGUgPSAyMSwgZmlsbCA9ICJibGFjayIpICsNCiAgICAgICMjIE4gIyMjDQogICAgICBhbm5vdGF0ZSgNCiAgICAgICAgInRleHQiLCB4ID0gLTAuOTMsIHkgPSAzLjg1LA0KICAgICAgICBsYWJlbCA9IHBhc3RlKCJpdGFsaWMoTik9PSIsIGxlbmd0aChkYXQucGxvdCRFUy5JRCkvMyksDQogICAgICAgIHBhcnNlID0gVFJVRSwgaGp1c3QgPSAibGVmdCIsIHNpemUgPSA1DQogICAgICApICsNCiAgICAgIGFubm90YXRlKA0KICAgICAgICAidGV4dCIsIHggPSAtMC42OCwgeSA9IDMuODUsDQogICAgICAgIGxhYmVsID0gImVhY2giLCBoanVzdCA9ICJsZWZ0Iiwgc2l6ZSA9IDUNCiAgICAgICkgKw0KICAgICAgeWxhYigiIikgKw0KICAgICAgeGxhYihleHByZXNzaW9uKA0KICAgICAgICBwYXN0ZSgiaHlwZXJib2xpYyB0YW5nZW50IG9mIGxuQ1ZSIGZyb20gIiwgaXRhbGljKCJzcFNTIikpLA0KICAgICAgICBwYXJzZSA9IFRSVUUNCiAgICAgICAgKSkgKw0KICAgICAgZ2d0aXRsZShjYXBbcGFzdGUodHIsIHRheG9uLHNlcD0iLiIpLF0pICsNCiAgICAgIG9yY2hhcmR0aGVtZSANCiAgICANCiAgICBwcmludChwbG90Lm1ldGFtZWFuKQ0KDQogICAgIyBnZ3NhdmUoDQogICAgIyAgIHBsb3QgPSBwbG90Lm1ldGFtZWFuLA0KICAgICMgICBmaWxlID0gcGFzdGUoIi4uL0FuYWx5c2lzL3ZhcmlhdGlvbi5nZW5lcmFsLm1ldGFtZWFuIiwgdHIsIHRheG9uLCAic3ZnIiwgc2VwID0gIi4iKSwNCiAgICAjICAgaGVpZ2h0ID0gNCwgd2lkdGggPSA1DQogICAgIyApDQoNCiAgfQ0KfQ0KDQpiaW5kX3Jvd3MoDQogIHJlcy5tYS5BbGx0cmFpdHMuYWxsdGF4b24sIHJlcy5tYS5Ob25ub3ZlbHRyYWl0cy5hbGx0YXhvbiwNCiAgcmVzLm1hLkFsbHRyYWl0cy5pbnNlY3QsIHJlcy5tYS5Ob25ub3ZlbHRyYWl0cy5pbnNlY3QNCiAgKSAlPiUNCiAgYXMuZGF0YS5mcmFtZSgpICU+JQ0KICBzZWxlY3QoRGF0YXNldCwgY3Jvc3MsIEVzdGltYXRlLCBVcHBlckNJLCBMb3dlckNJLCBjb250YWlucygiUFIiKSwgY29udGFpbnMoIkkyIikpICU+JQ0KICBrYWJsZSgiaHRtbCIsIGRpZ2l0cyA9IDMsIGNhcHRpb24gPSAiTWV0YS1hbmFseXNlcyByZXN1bHRzIG9mIGZ1bGwgZGF0YXNldCBhbmQgZGF0YSBzdWJzZXRzIikgJT4lIA0KICBrYWJsZV9zdHlsaW5nKCJzdHJpcGVkIiwgcG9zaXRpb24gPSAibGVmdCIpICU+JQ0KICBzY3JvbGxfYm94KHdpZHRoID0gIjEwMCUiLCBoZWlnaHQgPSAiNTAwcHgiKQ0KDQpgYGANCg0KDQoNCjxkaXYgc3R5bGU9Im1hcmdpbi1ib3R0b206NzBweDsiPg0KPC9kaXY+DQoNCiMjIENyb3NzaW5nIGRpcmVjdGlvbiBlZmZlY3QgaW4gcGhlbm90eXBpYyB2YXJpYWJpbGl0eSAoQ1YpDQoNCldlIHN0YXRpc3RpY2FsbHkgY29tcGFyZWQgbG5DVlIgZnJvbSA8aT5zcFNTPHN1Yj5NPC9zdWI+PC9pPiB0byB0aGUgb3RoZXIgY3Jvc3NlcyB0aHJvdWdoIHRoZSBmb3JtYWwgbWV0YS1yZWdyZXNzaW9uIGJ5IHVzaW5nIGBybWEubXZgIGZ1bmN0aW9uIG9mIFIgcGFja2FnZSBgbWV0YWZvcmAuIDxicj4gDQpIZXJlIHdlIGFza2VkIGlmIGxuQ1ZSIG9mIDxpPmh5YlNMPHN1Yj5WPC9zdWI+PC9pPiB3YXMgc21hbGxlci9sYXJnZXIgdGhhbiB0aGF0IG9mIDxpPmh5YkxTPHN1Yj5WPC9zdWI+PC9pPi4gU21hbGxlciBsbkNWUiBvZiA8aT5oeWJTTDxzdWI+Vjwvc3ViPjwvaT4gaW5kaWNhdGVzIG1hdGVybmFsIGluaGVyaXRhbmNlIGluIHBoZW5vdHlwaWMgdmFyaWFiaWxpdHkgPGJyPg0KDQpgYGB7cn0NCg0KZm9yICh0ciBpbiBjKCJBbGx0cmFpdHMiLCAiTm9ubm92ZWx0cmFpdHMiKSkgew0KICBmb3IgKHRheG9uIGluIGMoImFsbHRheG9uIiwgImluc2VjdCIpKSB7DQogICAgDQogICAgaWYgKHRheG9uID09ICJhbGx0YXhvbiIpIHsNCiAgICAgIGRhdCA8LSBOb3ZlbC5Ob25ub3ZlbCAlPiUgDQogICAgICAgIGZpbHRlcihkYXRhLnR5cGUgPT0gdHIpDQogICAgfSBlbHNlIHsNCiAgICAgIGRhdCA8LSBOb3ZlbC5Ob25ub3ZlbCAlPiUgDQogICAgICAgIGZpbHRlcihkYXRhLnR5cGUgPT0gdHIsIGluc2VjdCA9PSB0YXhvbikNCiAgICB9DQoNCiAgIysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysjDQogICMgcGh5bG9nZW5ldGljIHJhbmRvbSByZWdyZXNzb24gKEFOT1ZBKQ0KICAjKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyMNCiAgICANCiAgIyAjIFJlZ3Jlc3MgYnkgbG5DVlIgb2YgcGhlbm90eXBpYyBkaWZmZXJlbmNlIGJldHdlZW4gcGFyZW50YWxzDQogICMgcGh5bC5yYW5kb20uc3BMIDwtIHJtYS5tdigNCiAgIyAgIHlpID0gbG5DVlIuZXMsIFYgPSBsbkNWUi5zdiwNCiAgIyAgIGRhdGEgPSBkYXQsIG1ldGhvZCA9ICJSRU1MIiwNCiAgIyAgIHJhbmRvbSA9IGxpc3QofjEgfCBzcEwubmFtZSwgfjEgfCBTdHVkeS5JRCwgfjEgfCBDcm9zcy5JRCwgfjEgfCBFUy5JRCksDQogICMgICBSID0gbGlzdChzcEwubmFtZSA9IHBoeWxvX2NvciksDQogICMgICBtb2RzID0gfiByZWxldmVsKGNyb3NzLCByZWYgPSAic3BMIikNCiAgIyAgICkNCiAgIyBwaHlsLnJhbmRvbS5oeWJMUyA8LSBybWEubXYoDQogICMgICB5aSA9IGxuQ1ZSLmVzLCBWID0gbG5DVlIuc3YsDQogICMgICBkYXRhID0gZGF0LCBtZXRob2QgPSAiUkVNTCIsDQogICMgICByYW5kb20gPSBsaXN0KH4xIHwgc3BMLm5hbWUsIH4xIHwgU3R1ZHkuSUQsIH4xIHwgQ3Jvc3MuSUQsIH4xIHwgRVMuSUQpLA0KICAjICAgUiA9IGxpc3Qoc3BMLm5hbWUgPSBwaHlsb19jb3IpLA0KICAjICAgbW9kcyA9IH4gY3Jvc3MNCiAgIyAgICkNCiAgIyAjIFNhdmUgbW9kZWwgIyMjDQogICMgc2F2ZVJEUygNCiAgIyAgIHBoeWwucmFuZG9tLnNwTCwNCiAgIyAgIGZpbGUgPSBwYXN0ZSgiLi4vQW5hbHlzaXMvVmFyaWF0aW9uLmNvbXBhcmUuZnJvbS5zcEwiLCB0ciwgdGF4b24sICJvYmoiLCBzZXAgPSAiLiIpDQogICMgICApDQogICMgc2F2ZVJEUygNCiAgIyAgIHBoeWwucmFuZG9tLmh5YkxTLA0KICAjICAgZmlsZSA9IHBhc3RlKCIuLi9BbmFseXNpcy9WYXJpYXRpb24uY29tcGFyZS5mcm9tLmh5YkxTIiwgdHIsIHRheG9uLCAib2JqIiwgc2VwID0gIi4iKQ0KICAjICAgKQ0KICAgIA0KICAgIHBoeWwucmFuZG9tLmh5YkxTIDwtIHJlYWRSRFMoDQogICAgICBwYXN0ZSgiLi4vQW5hbHlzaXMvVmFyaWF0aW9uLmNvbXBhcmUuZnJvbS5oeWJMUyIsIHRyLCB0YXhvbiwgIm9iaiIsIHNlcCA9ICIuIikNCiAgICAgICkNCg0KICBhc3NpZ24oDQogICAgcGFzdGUoIlJlY2lwcm9jYWwiLCB0ciwgdGF4b24sIHNlcCA9ICIuIiksDQogICAgcGh5bC5yYW5kb20uaHliTFMgJT4lIA0KICAgICAgZ2V0X3JlZygpICU+JQ0KICAgICAgIyBTaG93IGRhdGFzZXQgbmFtZQ0KICAgICAgd2l0aGluKERhdGFzZXQgPC0gYyhwYXN0ZSh0ciwgdGF4b24pLCByZXAoIiIsIGxlbmd0aCguJEVzdGltYXRlKS0xKSkpICU+JQ0KICAgICAgIyBSZW5hbWUgZml4ZWQgZWZmZWN0cw0KICAgICAgd2l0aGluKCdGaXhlZCBlZmZlY3RzJyA8LSBjKCIiLCAiaHliTFMgKGludHJjcHQpIiwgImh5YlNMIiwgInNwTEwiKSkgJT4lDQogICAgICAjIERpZmZlcmVuY2Ugb2YgZWFjaCBjcm9zcyBmcm9tIG1pZHBhcmVudCBpbiAlDQogICAgICBtdXRhdGUoJ0NvbXBhcmlzb24gd2l0aCBoeWJyaWRMUycgPSBjKA0KICAgICAgICByZXAoIiIsIDIpLA0KICAgICAgICBwYXN0ZSgNCiAgICAgICAgICByb3VuZCgNCiAgICAgICAgICAgIChleHAocGh5bC5yYW5kb20uaHliTFMkYmV0YVsxXStwaHlsLnJhbmRvbS5oeWJMUyRiZXRhWzJdKSAtIGV4cChwaHlsLnJhbmRvbS5oeWJMUyRiZXRhWzFdKSkqMTAwLA0KICAgICAgICAgICAgMiksDQogICAgICAgICAgIiUgbGFyZ2VyIg0KICAgICAgICAgICksIA0KICAgICAgICAiIg0KICAgICAgICApDQogICAgICApDQogICAgKQ0KICB9DQp9DQoNCmJpbmRfcm93cygNCiAgUmVjaXByb2NhbC5BbGx0cmFpdHMuYWxsdGF4b24sIFJlY2lwcm9jYWwuTm9ubm92ZWx0cmFpdHMuYWxsdGF4b24sDQogIFJlY2lwcm9jYWwuQWxsdHJhaXRzLmluc2VjdCwgUmVjaXByb2NhbC5Ob25ub3ZlbHRyYWl0cy5pbnNlY3QNCiAgKSAlPiUNCiAga2FibGUoImh0bWwiLCBkaWdpdHMgPSAzLCBjYXB0aW9uID0gIlRhYmxlIFM2LiBSZXN1bHRzIG9mIG1ldGEtYW5hbHlzaXMgaW52ZXN0aWdhdGluZyBjcm9zcyBkaXJlY3Rpb24gZWZmZWN0IGluIHBoZW5vdHlwaWMgdmFyaWFiaWxpdGllcyB1c2luZyBmdWxsIGRhdGFzZXQgb3IgZGF0YSBzdWJzZXRzIikgJT4lIA0KICBrYWJsZV9zdHlsaW5nKCJzdHJpcGVkIiwgcG9zaXRpb24gPSAibGVmdCIpICU+JQ0KICBzY3JvbGxfYm94KHdpZHRoID0gIjEwMCUiLCBoZWlnaHQgPSAiNTAwcHgiKQ0KDQpgYGANCg0KDQoNCjxkaXYgc3R5bGU9Im1hcmdpbi1ib3R0b206MTgwcHg7Ij4NCjwvZGl2Pg0KIyBOb3ZlbHR5IGluIHBoZW5vdHlwaWMgbWVhbnMNCg0KIyMgRnJlcXVlbmN5DQoNCmBgYHtyfQ0KDQpkYXQuZnVsbCA8LSByZWFkLmNzdigiLi4vZGF0YS9tZWFuLkVTLk5vdmVsdHkuY3N2IiwgaGVhZCA9IFRSVUUpDQoNCiMjIE4gb2Ygbm92ZWwgcGhlbm90eXBlIGluIGVhY2ggdGF4YSBhbmQgZWFjaCBkaXJlY3Rpb24gIyMjDQpzdW1tYXJ5IDwtIGJpbmRfcm93cygNCiAgIyBBbGwgb2JzZXJ2YXRpb25zDQogIGRhdC5mdWxsICU+JQ0KICAgIGdyb3VwX2J5KHRheGEpICU+JQ0KICAgIHN1bW1hcmlzZSgNCiAgICAgICdTcGVjaWVzIHBhaXInID0gbGVuZ3RoKHVuaXF1ZShzcGVjaWVzLnBhaXIpKSwNCiAgICAgIE9ic2VydmF0aW9ucyA9IGxlbmd0aCh1bmlxdWUoRVMuSUQpKSwNCiAgICAgIFN0dWR5ID0gbGVuZ3RoKHVuaXF1ZShTdHVkeS5JRCkpDQogICAgICApICU+JQ0KICAgIG11dGF0ZShkaXJlY3Rpb24gPSAiQWxsIE9ic2VydmF0aW9ucyIpDQogICwNCiAgIyBub3ZlbCBwaGVub3R5cGUgZm9yIGFueSBkaXJlY3Rpb24NCiAgZGF0LmZ1bGwgJT4lDQogICAgZmlsdGVyKE5vdmVsdHkgPT0gIjEiKSAlPiUNCiAgICBncm91cF9ieSh0YXhhKSAlPiUNCiAgICBzdW1tYXJpc2UoDQogICAgICAnU3BlY2llcyBwYWlyJyA9IGxlbmd0aCh1bmlxdWUoc3BlY2llcy5wYWlyKSksDQogICAgICBPYnNlcnZhdGlvbnMgPSBsZW5ndGgodW5pcXVlKEVTLklEKSksDQogICAgICBTdHVkeSA9IGxlbmd0aCh1bmlxdWUoU3R1ZHkuSUQpKQ0KICAgICAgKSAlPiUNCiAgICBtdXRhdGUoZGlyZWN0aW9uID0gIk5vdmVsIHBoZW5vdHlwaWMgbWVhbnMiKQ0KICAsDQogICMgbm92ZWwgcGhlbm90eXBlIGZvciBlYWNoIGRpcmVjdGlvbg0KICBkYXQuZnVsbCAlPiUNCiAgICBmaWx0ZXIoTm92ZWx0eSA9PSAiMSIpICU+JQ0KICAgIGdyb3VwX2J5KHRheGEsIGRpcmVjdGlvbikgJT4lDQogICAgc3VtbWFyaXNlKA0KICAgICAgJ1NwZWNpZXMgcGFpcicgPSBsZW5ndGgodW5pcXVlKHNwZWNpZXMucGFpcikpLA0KICAgICAgT2JzZXJ2YXRpb25zID0gbGVuZ3RoKHVuaXF1ZShFUy5JRCkpLA0KICAgICAgU3R1ZHkgPSBsZW5ndGgodW5pcXVlKFN0dWR5LklEKSkNCiAgICAgICkNCiAgKSAlPiUNCiAgIyBBc3NpZ24gMCBmb3Igbm9uLW5vdmVsIHBoZW5vdHlwZQ0KICByZXBsYWNlKC4sIGlzLm5hKC4pLCAiMCIpICU+JSANCiAgIyBNYWtlIHRpZHkgZGF0YQ0KICBnYXRoZXIoa2V5ID0gbWV0cmljcywgdmFsdWUgPSBOLCAtYyh0YXhhLCBkaXJlY3Rpb24pKSAlPiUNCiAgIyBPcmRlciBmYWN0b3JzDQogIG11dGF0ZV9hdCh2YXJzKCJtZXRyaWNzIiwgImRpcmVjdGlvbiIpLCBhcy5mYWN0b3IpICU+JQ0KICBmaWx0ZXIobWV0cmljcyAhPSAiU3R1ZHkiKQ0KDQojIE9yZGVyIHRheG9uDQpzdW1tYXJ5JG1ldHJpY3MgPC0gb3JkZXJlZChzdW1tYXJ5JG1ldHJpY3MsIGxldmVscyA9IGMoIlN0dWR5IiwgIlNwZWNpZXMgcGFpciIsICJPYnNlcnZhdGlvbnMiKSkNCiMgT3JkZXIgbm92ZWwgcGhlbm90eXBlIGNhdGVnb3J5DQpzdW1tYXJ5JGRpcmVjdGlvbiA8LSBvcmRlcmVkKHN1bW1hcnkkZGlyZWN0aW9uLCBsZXZlbHMgPSBjKCJBbGwgT2JzZXJ2YXRpb25zIiwgIk5vdmVsIHBoZW5vdHlwaWMgbWVhbnMiLCAiKyIsICItIikpDQojIENoYW5nZSBuYW1lcyBvZiBUUyBjYXRlZ29yeSB0byBtb3JlIGludHVpdGl2ZSBuYW1lDQpsZXZlbHMoc3VtbWFyeSRkaXJlY3Rpb24pIDwtIGMoIkFsbCBPYnNlcnZhdGlvbnMiLCAiTm92ZWwgcGhlbm90eXBpYyBtZWFucyIsICJFeGNlZWQgdXBwZXIgcmFuZ2UiLCAiRXhjZWVkIGxvd2VyIHJhbmdlIikNCg0KIyMgUGxvdCAjIyMNCnBsb3QgPC0gZ2dwbG90KA0KICAjIHJlbmFtZSBsZXZlbHMgb2YgZmFjdG9ycyB0byB3cmFwIGxhYmVsIHRleHQNCiAgc3VtbWFyeSAlPiUNCiAgICB3aXRoaW4obGV2ZWxzKGRpcmVjdGlvbikgPC0gYygiQWxsIE9ic2VyLSB2YXRpb25zIiwgIk5vdmVsIHBoZW5vdHlwaWMgbWVhbnMiLCAiRXhjZWVkIHVwcGVyIHJhbmdlIiwgIkV4Y2VlZCBsb3dlciByYW5nZSIpKSAlPiUNCiAgICB3aXRoaW4obGV2ZWxzKG1ldHJpY3MpIDwtIGMoIlN0dWR5IiwgIlNwZWNpZXMgcGFpciIsICJPYnNlci0gdmF0aW9ucyIpKSwgDQogIGFlcyh4ID0gIiIsIHkgPSBOLCBmaWxsID0gdGF4YSkpICsNCiAgZ2VvbV9iYXIod2lkdGggPSAxLCBzdGF0ID0gImlkZW50aXR5IikgKw0KICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlBhaXJlZCIpICsNCiAgZmFjZXRfZ3JpZCgNCiAgICBzY2FsZSA9ICJmcmVlIiwgbWV0cmljcyB+IGRpcmVjdGlvbiwNCiAgICAjIHN0cmlwIHRleHQgaW50byB0d28gbGluZXMNCiAgICBsYWJlbGxlciA9IGxhYmVsX3dyYXBfZ2VuKHdpZHRoID0gMTApDQogICAgKSArDQogIHhsYWIoIiIpICsgeWxhYigiIikgKw0KICBzdGFja2VkYmFydGhlbWUNCnBsb3QgKw0KICBnZ3RpdGxlKCJUYXhvbm9taWMgZGlzdHJpYnV0aW9uIG9mIG5vdmVsIHBoZW5vdHlwaWMgbWVhbnMiKQ0KDQojIGdnc2F2ZSgNCiMgICBwbG90ID0gcGxvdCwgDQojICAgZmlsZSA9ICIuLi9BbmFseXNpcy9tZWFuLlRTLmZyZXF1ZW5jeS5zdmciLCBoZWlnaHQgPSAzLjcsIHdpZHRoID0gNS4wDQojICAgKQ0KDQojIyBUb3RhbCBudW1iZXIgb2Ygb2JzZXJ2YXRpb25zIGFuZCBwZXJjZW50YWdlICMjIw0Kc3VtbWFyeSAlPiUNCiAgZ3JvdXBfYnkoZGlyZWN0aW9uLCBtZXRyaWNzKSAlPiUNCiAgIyBDb3VudCBudW1iZXIgb2Ygb2JzZXJ2YWl0b25zIGFuZCBzcGVjaWVzIHBhaXJzDQogIHN1bW1hcmlzZShzdW0oTikpICU+JQ0KICBzcHJlYWQoa2V5ID0gbWV0cmljcywgdmFsdWUgPSAic3VtKE4pIikgJT4lDQogIGFzLmRhdGEuZnJhbWUoKSAlPiUNCiAgIyBDYWxjdWxhdGUgcGVyY2VudGFnZQ0KICBtdXRhdGUoDQogICAgJ1NwZWNpZXMgcGFpciAlJyA9IC5bLCAiU3BlY2llcyBwYWlyIl0vLlsxLCAiU3BlY2llcyBwYWlyIl0qMTAwLA0KICAgICdPYnNlcnZhdG9uICUnID0gT2JzZXJ2YXRpb25zLy5bMSwgIk9ic2VydmF0aW9ucyJdKjEwMA0KICApICU+JQ0KICBtdXRhdGVfYXQodmFycyhjb250YWlucygicGVyY2VudCIpKSwgcm91bmQsIDIpICU+JQ0KICBrYWJsZSgiaHRtbCIsIGRpZ2l0cyA9IDMsIGNhcHRpb24gPSAiU3VtbWFyeSBvZiB0aGUgbm92ZWwgcGhlbm90eXBpYyBtZWFucyBmcmVxdWVuY3kiKSAlPiUgDQogIGthYmxlX3N0eWxpbmcoInN0cmlwZWQiLCBwb3NpdGlvbiA9ICJsZWZ0IikNCg0KYGBgDQoNCjxkaXYgc3R5bGU9Im1hcmdpbi1ib3R0b206NzBweDsiPg0KPC9kaXY+DQoNCg0KIyMgRmFjdG9ycyBhZmZlY3RpbmcgIHBoZW5vdHlwaWMgbm92ZWx0eQ0KV2UgY2hlY2tlZCByb2J1c3RuZXNzIG9mIHJlc3VsdHMgYnkgY29uZHVjdGluZyBpZGVudGljYWwgYW5hbHlzaXMgZm9yIGBpbnNlY3RgIHN1YnNldCBkYXRhIChyZW1vdmluZyB2ZXJ0ZWJyYXRlIGRhdGEpLiA8YnI+DQoNCk1vZGVsLCB3aGljaCB3YXMgcmFuIHVzaW5nIGBNQ01DZ2xtbWAgZnVuY3Rpb24sIGluY2x1ZGVkIGZvbGxvd2luZyBSYW5kb20gZWZmZWN0cyBlc3RpbWF0ZXM6IA0KDQoqIGBTdHVkeS5JRGA6IFByaW1hcnkgc3R1ZGllcw0KDQoqIGBDcm9zcy5JRGA6IFBhcmVudGFsIHN0cmFpbiB1c2VkIGluIHRoZSBjcm9zc2luZy4gRGlzY3JpbWluYXRlIGludHJhc3BlY2lmaWMgcG9wdWxhdGlvbnMNCg0KKiBgc3BMLm5hbWVgOiBQaHlsb2dlbnkgb2YgcGFyZW50YWwgc3BlY2llcyAoPGk+c3BMTDxzdWI+TTwvc3ViPjwvaT4pDQoNCiogYFNFLnVuaXRzYDogU2FtcGxpbmcgdmFyaWFuY2Ugb2YgZWZmZWN0IHNpemUNCg0KVGhlIG1vZGVyYXRvcnMgd2VyZSBjYXRlZ29yaXNlZCBpbnRvIDMgc3Vic2V0czogbWFpbiBlZmZlY3RzIChsYWJlbGxlZCBhcyBgbm92ZWx0eSBpbiBwaGVub3R5cGljIG1lYW5zYCksIGludGVyYWN0aW9uIHRlcm1zIHdpdGggY29tcGFyZWQgcGFyZW50YWwgc3BlY2llcyAoc3BMTCB2cy4gc3BTUywgbGFiZWxsZWQgYXMgYGV4Y2VlZCB1cHBlciByYW5nZWA7IG1vdGhlciBzcGVjaWVzIHZzLiBmYXRoZXIsIGxhYmVsbGVkIGFzIGBleGNlZWQgbW90aGVyYCkuIA0KDQpgYGB7ciwgcmVzdWx0cyA9ICdhc2lzJ30NCg0KIyBDb3JyZWN0aW5nIGVzdGltYXRlIG9mIGJpbm9taWFsIHJlZ3Jlc3Npb24NCmMyIDwtICgxNiAqIHNxcnQoMykvKDE1ICogcGkpKV4yDQoNCg0KIysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysjDQojIFBoeWxvZ2VuZXRpYyB0cmVlIGZvciBtY21jZ2xtbSANCiMrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrIw0KIyBjb21wdXRlIGJyYW5jaCBsZW5ndGhzIG9mIHRyZWUNCnBoeWxvX2JyYW5jaCA8LSByZWFkLnRyZWUoZmlsZSA9ICIuLi9kYXRhL3BoeWxvLm1lYW4udHJlIikgJT4lDQogIGNvbXB1dGUuYnJsZW4obWV0aG9kID0gIkdyYWZlbiIsIHBvd2VyID0gMSkNCg0KIyBzYXZpbmcgcGh5bG9nZW5laWMgbWF0cml4DQpwaHlsb19jb3IgPC0gdmN2KHBoeWxvX2JyYW5jaCwgY29yID0gVCkNCg0KIyBnZW5lcmF0aW5nIGludmVyc2UgcGh5bG9nZW5ldGljIG1hdHJpeCBmb3IgTUNNQ2dsbW0NCnBoeWxvX2JyYW5jaCRub2RlLmxhYmVsIDwtIE5VTEwNCnBoeWxvX01DTUMgPC0gTUNNQ2dsbW06OmludmVyc2VBKHBoeWxvX2JyYW5jaCwgbm9kZXMgPSAiQUxMIiwgc2NhbGUgPSBUUlVFKSRBaW52DQoNCiMgQ2FwdGlvbg0KY2FwIDwtIGRhdGEuZnJhbWUoDQogIGRlc2MgPSBjKA0KICAgICJUYWJsZSBTNy4gRml4ZWQgZWZmZWN0cyBlc3RpbWF0ZXMgb2YgQmF5ZXNpYW4gbG9naXN0aWMgbW9kZWwgaW52ZXN0aWdhdGluZyBmYWN0b3JzIGFmZmVjdGluZyBub3ZlbHR5IGluIHBoZW5vdHlwaWMgbWVhbnMuIERhdGEgb2YgYWxsIHRheG9uIHdhcyB1c2VkIiwNCiAgICAiRml4ZWQgZWZmZWN0cyBlc3RpbWF0ZXM6IGluc2VjdCBzdWJzZXQgZGF0YSINCiAgICApDQogICkgJT4lDQogIG11dGF0ZV9hbGwoYXMuY2hhcmFjdGVyKQ0Kcm93Lm5hbWVzKGNhcCkgPC0gYygiYWxsdGF4b24iLCAiaW5zZWN0IikNCg0KZm9yICh0YXhvbiBpbiBjKCJhbGx0YXhvbiIsICJpbnNlY3QiKSkgew0KICANCiAgaWYgKHRheG9uID09ICJhbGx0YXhvbiIpIHsNCiAgICBkYXQgPC0gZGF0LmZ1bGwNCiAgfSBlbHNlIHsNCiAgICBkYXQgPC0gZGF0LmZ1bGwgJT4lIA0KICAgICAgZmlsdGVyKGluc2VjdCA9PSB0YXhvbikNCiAgfQ0KDQogICMgIyMgU2V0dGluZyBwcmlvciB0byBsb2dpc3RpYyByZWdyZXNzaW9uICMjIw0KICAjIHByaW9yIDwtIGxpc3QoDQogICMgICBCPWxpc3QoDQogICMgICAgIG11ID0gcmVwKDAsIDE3KSwgIyBOIG9mIGNvZWZmaWNpZW50LiAobGV2ZWwgLTEpIGZvciBjYXRlZ29yaWNhbCBmYWN0b3JzLCAxIGZvciBjb250aW51b3VzIGZhY3RvcnMsIDEgZm9yIGludGVyY2VwdA0KICAjICAgICBWID0gZ2VsbWFuLnByaW9yKH4NCiAgIyAgICAgICBwYXJlbnRhbCpIZXRlcm8uc2V4ICsNCiAgIyAgICAgICBwYXJlbnRhbCpkaXJlY3Rpb24gKw0KICAjICAgICAgIGRpcmVjdGlvbipHZW5ldC5kaXZlcmdlbmNlICsgZGlyZWN0aW9uKlBoZW5vLmRpdmVyZ2VuY2UgKw0KICAjICAgICAgIGRpcmVjdGlvbipIZXRlcm8uc2V4ICsNCiAgIyAgICAgICBkaXJlY3Rpb24qdHJhaXQudHlwZSArDQogICMgICAgICAgZGlyZWN0aW9uKkRpc3RyaWJ1dGlvbiArIGRpcmVjdGlvbipSZWNpcHJvY2FsLA0KICAjICAgICBkYXRhID0gZGF0LCAjIGZvcm11bGEgYW5kIGRhdGENCiAgIyAgICAgc2NhbGU9c3FydChwaV4yLzMrMSkpKSwgIyBlcnJvciBkaXN0cmlidXRpb24gb2YgbG9naXN0aWMgcmVncmVzc2lvbg0KICAjICAgUj1saXN0KFY9MSxmaXg9MSksDQogICMgICBHID0gbGlzdCgNCiAgIyAgICAgRzEgPSBsaXN0KFYgPSAxLCBudSA9IDEsIGFscGhhLm11ID0gMCwgYWxwaGEuViA9IDEwMDApLA0KICAjICAgICBHMiA9IGxpc3QoViA9IDEsIG51ID0gMSwgYWxwaGEubXUgPSAwLCBhbHBoYS5WID0gMTAwMCksDQogICMgICAgIEczID0gbGlzdChWID0gMSwgbnUgPSAxLCBhbHBoYS5tdSA9IDAsIGFscGhhLlYgPSAxMDAwKSwNCiAgIyAgICAgRzQgPSBsaXN0KFYgPSAxLCBudSA9IDEsIGFscGhhLm11ID0gMCwgYWxwaGEuViA9IDEwMDApDQogICMgICAgICkNCiAgIyAgICkNCiAgIyAjIyBQaHlsb2dlbmV0aWMgYmlub21pYWwgcmVncmVzc2lvbiAjIyMNCiAgIyBwaHlsbWl4IDwtTUNNQ2dsbW0oDQogICMgICBmaXhlZCA9IE5vdmVsdHkgfg0KICAjICAgICBwYXJlbnRhbCpIZXRlcm8uc2V4ICsgcGFyZW50YWwqZGlyZWN0aW9uICsNCiAgIyAgICAgZGlyZWN0aW9uKkdlbmV0LmRpdmVyZ2VuY2UgKyBkaXJlY3Rpb24qUGhlbm8uZGl2ZXJnZW5jZSArDQogICMgICAgIGRpcmVjdGlvbipIZXRlcm8uc2V4ICsgZGlyZWN0aW9uKnRyYWl0LnR5cGUgKw0KICAjICAgICBkaXJlY3Rpb24qRGlzdHJpYnV0aW9uICsgZGlyZWN0aW9uKlJlY2lwcm9jYWwsDQogICMgICAjIGlkaChTRSk6dW5pdHMgfCB3ZWlnaHQgYnkgU0Ugb2YgZWZmZWN0IHNpemUNCiAgIyAgIHJhbmRvbSA9IH4gU3R1ZHkuSUQgKyBDcm9zcy5JRCArIHNwTC5uYW1lICsgaWRoKFNFKTp1bml0cywNCiAgIyAgIGZhbWlseSA9ICJjYXRlZ29yaWNhbCIsDQogICMgICB2ZXJib3NlID0gRkFMU0UsDQogICMgICBnaW52ZXJzZSA9IGxpc3Qoc3BMLm5hbWUgPSBwaHlsb19NQ01DKSwNCiAgIyAgIHByaW9yID0gcHJpb3IsDQogICMgICBkYXRhID0gZGF0LA0KICAjICAgbml0dCA9IDYwMDAwLCAgIyBJbmNyZWFzZSB0aGUgbnVtYmVyIG9mIGl0ZXJhdGlvbnMsIGRlZmF1bHQgaXMgMTMwMDANCiAgIyAgIGJ1cm5pbiA9IDUwMDAgICMgSW5jcmVhc2UgdGhlIG51bWJlciBvZiBidXJuaW4sIGRlZmF1bHQgaXMgMzAwMA0KICAjICkNCiAgIyBwaHlsbWl4JFNvbCA8LSBwaHlsbWl4JFNvbC9zcXJ0KDErYzIpDQogICMgIyMgU2F2ZSBtb2RlbCAjIyMNCiAgIyBzYXZlUkRTKHBoeWxtaXgsIGZpbGUgPSBwYXN0ZSgiLi4vQW5hbHlzaXMvTWVhbi5ub3ZlbHR5LmFsbGZhY3RvcnMiLCB0YXhvbiwgIm9iaiIsIHNlcCA9ICIuIikpDQoNCiAgIysrKysrKysrKysrKysrKysrKysrKysrIw0KICAjIEdyb3VwaW5nIHZhcmlhYmxlcw0KICAjKysrKysrKysrKysrKysrKysrKysrKysjDQogICMgTG9hZCBtb2RlbA0KICBwaHlsbWl4IDwtIHJlYWRSRFMocGFzdGUoIi4uL0FuYWx5c2lzL01lYW4ubm92ZWx0eS5hbGxmYWN0b3JzIiwgdGF4b24sICJvYmoiLCBzZXAgPSAiLiIpKQ0KICANCiAgc3VtIDwtIGdldF9maXhlZC5NQ01DZ2xtbShzdW1tYXJ5KHBoeWxtaXgpJHNvbHV0aW9ucykgJT4lDQogICAgICAjIyBHcm91cGluZyBGYWN0b3JzICMjIw0KICAgICAgbXV0YXRlKA0KICAgICAgICBHcm91cCA9IA0KICAgICAgICAgIGlmZWxzZShzdHJfZGV0ZWN0KEZhY3RvcnMsICJkaXJlY3Rpb24uOiIpLCANCiAgICAgICAgICAgICAgICAgIkV4Y2VlZCB1cHBlciByYW5nZSIsDQogICAgICAgICAgICAgICAgIGlmZWxzZShzdHJfZGV0ZWN0KEZhY3RvcnMsICJwYXJlbnRhbE1vdGhlcjoiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICJFeGNlZWQgbW90aGVyIiwNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShGYWN0b3JzID09ICJIZXRlcm8uc2V4TWFsZTpkaXJlY3Rpb24rIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRXhjZWVkIHVwcGVyIHJhbmdlIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiSW5jcmVhc2Ugbm92ZWx0eSINCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICkNCiAgICAgICkgJT4lDQogICAgICBtdXRhdGVfYXQoIkdyb3VwIiwgYXMuZmFjdG9yKSAlPiUNCiAgICAgIHdpdGhpbihHcm91cCA8LSBvcmRlcmVkKEdyb3VwLCBjKCJJbmNyZWFzZSBub3ZlbHR5IiwgIkV4Y2VlZCB1cHBlciByYW5nZSIsICJFeGNlZWQgbW90aGVyIikpKSAlPiUNCiAgICAgICMjIENoYW5nZSBmYWN0b3IgbmFtZXMgIyMjDQogICAgICB3aXRoaW4oDQogICAgICAgIEZhY3RvcnMgPC0gc3RyX3JlbW92ZV9hbGwoDQogICAgICAgICAgRmFjdG9ycywgImRpcmVjdGlvbi46Ig0KICAgICAgICAgICkgJT4lDQogICAgICAgICAgc3RyX3JlbW92ZV9hbGwoLiwgInBhcmVudGFsTW90aGVyOiIpICU+JQ0KICAgICAgICAgIHN0cl9yZW1vdmVfYWxsKC4sICI6ZGlyZWN0aW9uLiIpDQogICAgICAgICkgJT4lDQogICAgICB3aXRoaW4oDQogICAgICAgIEZhY3RvcnMgPC0gZmFjdG9yKA0KICAgICAgICAgIEZhY3RvcnMsIG9yZGVyZWQgPSBUUlVFLCANCiAgICAgICAgICBsZXZlbHMgPSBjKCJwYXJlbnRhbE1vdGhlciIsICJkaXJlY3Rpb24rIiwgInRyYWl0LnR5cGVzb3VuZCIsICJIZXRlcm8uc2V4TWFsZSIsICJSZWNpcHJvY2FsVmlhYmxlIiwgIkRpc3RyaWJ1dGlvbk92ZXJsYXAiLCAiUGhlbm8uZGl2ZXJnZW5jZSIsICAiR2VuZXQuZGl2ZXJnZW5jZSIsICAiKEludGVyY2VwdCkiKQ0KICAgICAgICAgICkNCiAgICAgICAgKQ0KICBsZXZlbHMoc3VtJEZhY3RvcnMpIDwtIGMoIkV4Y2VlZCBtb3RoZXIiLCAiRXhjZWVkIHVwcGVyIHJhbmdlIiwgIlNvdW5kIHRyYWl0cyIsICJNYWxlIGhldGVyb2dhbWV0aWMiLCAiVmlhYmxlIHJlY2lwcm9jYWwgaHlicmlkcyIsICJEaXN0cmlidXRpb24gb3ZlcmxhcCIsICJQaGVub3R5cGljIGRpdmVyZ2VuY2UiLCAiR2VuZXRpYyBkaXZlcmdlbmNlIiwgIkludGVyY2VwdCIpDQoNCiAgIyMgUGxvdCAjIyMNCiAgbWV0YXBsb3QgPC0gZ2dwbG90KHN1bSwgYWVzKHggPSBwb3N0Lm1lYW4sIHkgPSBGYWN0b3JzKSkgKw0KICAgICMgVmVydGljYWwgbGluZQ0KICAgIGdlb21fdmxpbmUoDQogICAgICB4aW50ZXJjZXB0ID0gMCwgc2l6ZSA9IDAuMiwgDQogICAgICBjb2xvdXIgPSAiZ3JleTMwIiwgbGluZXR5cGUgPSAiZG90dGVkIiAgICAgICAgIA0KICAgICAgKSArDQogICAgIyBDSQ0KICAgIGdlb21fZXJyb3JiYXJoKA0KICAgICAgYWVzKA0KICAgICAgICB4bWluID0gc3VtWywgJ2wtOTUlIENJJ10sIHhtYXggPSBzdW1bLCAndS05NSUgQ0knXSwNCiAgICAgICAgY29sb3VyPXNpZ25pZmljYW5jZSANCiAgICAgICAgKSwgDQogICAgICBoZWlnaHQgPSAuMDAwMQ0KICAgICAgKSArDQogICAgIyBDb2xvciBvZiBwbG90cyBhbmQgZXJyb3JiYXJzDQogICAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKCJncmV5NjAiLCAiYmxhY2siKSkgKw0KICAgIGdlb21fcG9pbnQoc2l6ZSA9IDEsIGFlcyhjb2xvdXIgPSBzaWduaWZpY2FuY2UpKSArDQogICAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiZ3JleTYwIiwgImJsYWNrIikpICsNCiAgICAjIFRpdGxlDQogICAgZ2d0aXRsZShwYXN0ZSgiRml4ZWQgZWZmZWN0cyBlc3RpbWF0ZXMgdXNpbmciLCB0YXhvbiwgImRhdGEiKSkgKw0KICAgIHlsYWIoIiIpICsgeGxhYigiRXN0aW1hdGUgd2l0aCA5NSUgQ0kiKSArDQogICAgIyBDb21iaW5lIGRpZmZlcmVudCBwbG90cyBmb3IgbWFpbiBGYWN0b3JzIGFuZCBpbnRlcmFjdGlvbnMNCiAgICBmYWNldF9ncmlkKA0KICAgICAgR3JvdXB+Liwgc2NhbGVzID0gImZyZWUiLCBzcGFjZSA9ICJmcmVlIiwNCiAgICAgIGxhYmVsbGVyID0gbGFiZWxfd3JhcF9nZW4od2lkdGggPSAyMCkNCiAgICAgICkgKw0KICAgICMgVGhlbWVzDQogICAgZm9yZXN0dGhlbWUNCnByaW50KG1ldGFwbG90KQ0KDQogICMgZ2dzYXZlKA0KICAjICAgICBwbG90ID0gbWV0YXBsb3QsDQogICMgICAgIGZpbGUgPSBwYXN0ZSgiLi4vQW5hbHlzaXMvbWVhbi5ub3ZlbHR5LnJlc3VsdCIsIHRheG9uLCAic3ZnIiwgc2VwID0gIi4iKSwNCiAgIyAgICAgaGVpZ2h0ID0gNC43LCB3aWR0aCA9IDQuMA0KICAjICAgICApDQoNCiAgIysrKysrKysrKysrKysrKysrKysrKysrKysjDQogICMgRml4ZWQgZWZmZWN0cyBvdXRwdXQNCiAgIysrKysrKysrKysrKysrKysrKysrKysrKysjDQogIHN1bSAlPiUgDQogICAgc2VsZWN0KEdyb3VwLCBGYWN0b3JzLCBFc3RpbWF0ZXMsICc5NSUgY3JlZGlibGUgaW50ZXJ2YWwnLCBQLCBzaWduaWZpY2FuY2UsIERlc2NyaXB0aW9uKSAlPiUNCiAgICBrYWJsZSgiaHRtbCIsIGNhcHRpb24gPSBjYXBbdGF4b24sXSkgJT4lIA0KICAgIGthYmxlX3N0eWxpbmcoInN0cmlwZWQiLCBwb3NpdGlvbiA9ICJsZWZ0IikgJT4lDQogICAgc2Nyb2xsX2JveCh3aWR0aCA9ICIxMDAlIiwgaGVpZ2h0ID0gIjUwMHB4IikgJT4lDQogICAgcHJpbnQoKQ0KICANCiAgIysrKysrKysrKysrKysrKysrKysrKysrKysrKyMNCiAgIyBSYW5kb20gZWZmZWN0cyBvdXRwdXQgDQogICMrKysrKysrKysrKysrKysrKysrKysrKysrKysjDQogICMgdHJhbnNmb3JtYXRpb24gZm9yIHZhcmFpbmNlDQogIGdldF9yYW5kb20uTUNNQ2dsbW0oc3VtbWFyeShwaHlsbWl4JFZDVi8oMStjMikpKSAlPiUNCiAgICBrYWJsZSgiaHRtbCIsIGRpZ2l0cyA9IDIsDQogICAgICAgICAgY2FwdGlvbiA9IHBhc3RlKCJSYW5kb20gZWZmZWN0cyBlc3RpbWF0ZXM6ICIsIHRheG9uLCAiZGF0YSIsICIgIikNCiAgICAgICAgICApICU+JSANCiAgICBrYWJsZV9zdHlsaW5nKCJzdHJpcGVkIiwgcG9zaXRpb24gPSAibGVmdCIpICU+JQ0KICAgIHByaW50KCkNCg0KfQ0KDQpgYGANCldoaWxlIG9uZSBvZiBzaWduaWZpY2FudCBtb2RlcmF0b3JzIChgUmVjaXByb2NhbCBoeWJyaWRzYCkgYmVjb21lIG5vIGxvbmdlciBzaWduaWZpY2FudCBpbiBgaW5zZWN0YCBzdWJzZXQgZGF0YSwgZWZmZWN0cyBhcmUgcXVhbGl0YXRpdmVseSB0aGUgc2FtZSBpbiBzaWduLiANCg0KDQo8ZGl2IHN0eWxlPSJtYXJnaW4tYm90dG9tOjcwcHg7Ij4NCjwvZGl2Pg0KDQojIyBFZmZlY3RzIG9mIHNpZ25pZmljYW50IG1vZGVyYXRvcnMgDQpUbyB2aXN1YWxseSBpbnRlcnByZXQgdGhlIGltcGFjdHMgb2Ygc2lnbmlmaWNhbnQgbW9kZXJhdG9ycywgd2UgYWRkaXRpb25hbGx5IGNvbmR1Y3RlZCBzaW1wbGVyIG1vZGVscyBmb3IgZWFjaCBzaWduaWZpY2FudCBmYWN0b3IuIEFzIG1vZGVyYXRvcnMsIHdlIGluY2x1ZGVkIHRoZSBmb2NhbCBmYWN0b3JzLCB0aGUgY29tcGFyZWQgcGFyZW50YWwgc3BlY2llcyDigJMgc3BMTCBvciBzcFNTLCBhbmQgdGhlIGludGVyYWN0aW9uIGJldHdlZW4gdGhlbS4gUmVzcG9uc2UgdmFyaWFibGVzIGFuZCByYW5kb20gZWZmZWN0cyBvZiBzaW1wZXIgbW9kZWxzIHdlcmUgaWRlbnRpY2FsIHRvIGZ1bGwgbW9kZWxzLiANCg0KYGBge3IsIGZpZy5oZWlnaHQgPSAzLjUsIGZpZy53aWR0aCA9IDMuM30NCg0KIyArKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrIw0KIyBUbyBzZXQgcmF3IG1ldGFkYXRhIGluIFggYXhpcywgcmVsb2FkIHJhdyBtZXRhZGF0YSBhbmQgY29tYmluZSB0byBub3ZlbHR5IGRhdGFzZXQNCiMgKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyMNCnJhd2RhdCA8LSBkYXQuZnVsbCAlPiUNCiAgc2VsZWN0KC1QaGVuby5kaXZlcmdlbmNlLCAtR2VuZXQuZGl2ZXJnZW5jZSkgJT4lDQogICMgbG5SUiBiZXR3ZWVuIHBhcmVudGFsIHNwZWNpZXMgYXMgcGhlbm90eXBpYyBkaXN0YW5jZQ0KICBtdXRhdGUoUGhlbm8uZGl2ZXJnZW5jZSA9IGxvZyhNbi5zcEwvTW4uc3BTKSkgJT4lDQogIGxlZnRfam9pbigNCiAgICAuLA0KICAgIHJlYWQueGxzeCgiLi4vZGF0YS9vcmlnaW5hbC5kYXRhLnhsc3giLCBzaGVldCA9ICJTcGVjaWVzLmxldmVsLm1vZGVyYXRvcnMiKSAlPiUNCiAgICAgIHNlbGVjdChDcm9zcy5JRCwgR2VuZXQuZGl2ZXJnZW5jZSkNCiAgICApICU+JQ0KICAjIE5hdHVyYWwgbG9nIG9mIGdlbmV0aWMgZGlzdGFuY2UNCiAgbXV0YXRlX2F0KCJHZW5ldC5kaXZlcmdlbmNlIiwgbG9nKSAlPiUNCiAgbXV0YXRlX2F0KCJkaXJlY3Rpb24iLCBhcy5mYWN0b3IpDQoNCiMgKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyMNCiMgUmVncmVzc2lvbjogR2VuZXRpYyBkaXN0YW5jZQ0KIyArKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrIw0KDQojICMjIFNldHRpbmcgcHJpb3IgdG8gbG9naXN0aWMgcmVncmVzc2lvbiAjIyMNCiMgcHJpb3IgPC0gbGlzdCgNCiMgICBCPWxpc3QoDQojICAgICBtdSA9IHJlcCgwLCAzKSwgIyBOIG9mIGNvZWZmaWNpZW50LiAobGV2ZWwgLTEpIGZvciBjYXRlZ29yaWNhbCBmYWN0b3JzLCAxIGZvciBjb250aW51b3VzIGZhY3RvcnMsIDEgZm9yIGludGVyY2VwdA0KIyAgICAgViA9IGdlbG1hbi5wcmlvcih+IGRpcmVjdGlvbjpHZW5ldC5kaXZlcmdlbmNlICsgR2VuZXQuZGl2ZXJnZW5jZSwNCiMgICAgIGRhdGEgPSByYXdkYXQsICMgZm9ybXVsYSBhbmQgZGF0YQ0KIyAgICAgc2NhbGU9c3FydChwaV4yLzMrMSkpKSwgIyBlcnJvciBkaXN0cmlidXRpb24gb2YgbG9naXN0aWMgcmVncmVzc2lvbg0KIyAgIFI9bGlzdChWPTEsZml4PTEpLA0KIyAgIEcgPSBsaXN0KA0KIyAgICAgRzEgPSBsaXN0KFYgPSAxLCBudSA9IDEsIGFscGhhLm11ID0gMCwgYWxwaGEuViA9IDEwMDApLA0KIyAgICAgRzIgPSBsaXN0KFYgPSAxLCBudSA9IDEsIGFscGhhLm11ID0gMCwgYWxwaGEuViA9IDEwMDApLA0KIyAgICAgRzMgPSBsaXN0KFYgPSAxLCBudSA9IDEsIGFscGhhLm11ID0gMCwgYWxwaGEuViA9IDEwMDApLA0KIyAgICAgRzQgPSBsaXN0KFYgPSAxLCBudSA9IDEsIGFscGhhLm11ID0gMCwgYWxwaGEuViA9IDEwMDApDQojICAgICApDQojICAgKQ0KIyAjIyBQaHlsb2dlbmV0aWMgYmlub21pYWwgcmVncmVzc2lvbiAjIyMNCiMgcGh5bG1peCA8LU1DTUNnbG1tKA0KIyAgIGZpeGVkID0gTm92ZWx0eSB+IGRpcmVjdGlvbjpHZW5ldC5kaXZlcmdlbmNlICsgR2VuZXQuZGl2ZXJnZW5jZSwNCiMgICAjIGlkaChTRSk6dW5pdHMgfCB3ZWlnaHQgYnkgU0Ugb2YgZWZmZWN0IHNpemUNCiMgICByYW5kb20gPSB+IFN0dWR5LklEICsgQ3Jvc3MuSUQgKyBzcEwubmFtZSArIGlkaChTRSk6dW5pdHMsDQojICAgZmFtaWx5ID0gImNhdGVnb3JpY2FsIiwNCiMgICB2ZXJib3NlID0gRkFMU0UsDQojICAgZ2ludmVyc2UgPSBsaXN0KHNwTC5uYW1lID0gcGh5bG9fTUNNQyksDQojICAgcHJpb3IgPSBwcmlvciwNCiMgICBkYXRhID0gcmF3ZGF0LA0KIyAgIG5pdHQgPSA2MDAwMCwgICMgSW5jcmVhc2UgdGhlIG51bWJlciBvZiBpdGVyYXRpb25zLCBkZWZhdWx0IGlzIDEzMDAwDQojICAgYnVybmluID0gNTAwMCAgIyBJbmNyZWFzZSB0aGUgbnVtYmVyIG9mIGJ1cm5pbiwgZGVmYXVsdCBpcyAzMDAwDQojICkNCiMgcGh5bG1peCRTb2wgPC0gcGh5bG1peCRTb2wvc3FydCgxK2MyKQ0KIyAjIyBTYXZlIG1vZGVsICMjIw0KIyBzYXZlUkRTKHBoeWxtaXgsIGZpbGUgPSIuLi9BbmFseXNpcy9NZWFuLm5vdmVsdHkuR2VuZXQuZGl2ZXJnZW5jZS5vYmoiKQ0KDQojICsrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysjDQojIFJlZ3Jlc3Npb246IFBoZW5vdHlwaWMgZGl2ZXJnZW5jZQ0KIyArKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrIw0KIyAjIyBTZXR0aW5nIHByaW9yIHRvIGxvZ2lzdGljIHJlZ3Jlc3Npb24gIyMjDQojIHByaW9yIDwtIGxpc3QoDQojICAgQj1saXN0KA0KIyAgICAgbXUgPSByZXAoMCwgMyksICMgTiBvZiBjb2VmZmljaWVudC4gKGxldmVsIC0xKSBmb3IgY2F0ZWdvcmljYWwgZmFjdG9ycywgMSBmb3IgY29udGludW91cyBmYWN0b3JzLCAxIGZvciBpbnRlcmNlcHQNCiMgICAgIFYgPSBnZWxtYW4ucHJpb3IofiBkaXJlY3Rpb246UGhlbm8uZGl2ZXJnZW5jZSArIFBoZW5vLmRpdmVyZ2VuY2UsDQojICAgICBkYXRhID0gcmF3ZGF0LCAjIGZvcm11bGEgYW5kIGRhdGENCiMgICAgIHNjYWxlPXNxcnQocGleMi8zKzEpKSksICMgZXJyb3IgZGlzdHJpYnV0aW9uIG9mIGxvZ2lzdGljIHJlZ3Jlc3Npb24NCiMgICBSPWxpc3QoVj0xLGZpeD0xKSwNCiMgICBHID0gbGlzdCgNCiMgICAgIEcxID0gbGlzdChWID0gMSwgbnUgPSAxLCBhbHBoYS5tdSA9IDAsIGFscGhhLlYgPSAxMDAwKSwNCiMgICAgIEcyID0gbGlzdChWID0gMSwgbnUgPSAxLCBhbHBoYS5tdSA9IDAsIGFscGhhLlYgPSAxMDAwKSwNCiMgICAgIEczID0gbGlzdChWID0gMSwgbnUgPSAxLCBhbHBoYS5tdSA9IDAsIGFscGhhLlYgPSAxMDAwKSwNCiMgICAgIEc0ID0gbGlzdChWID0gMSwgbnUgPSAxLCBhbHBoYS5tdSA9IDAsIGFscGhhLlYgPSAxMDAwKQ0KIyAgICAgKQ0KIyAgICkNCiMgIyMgUGh5bG9nZW5ldGljIGJpbm9taWFsIHJlZ3Jlc3Npb24gIyMjDQojIHBoeWxtaXggPC1NQ01DZ2xtbSgNCiMgICBmaXhlZCA9IE5vdmVsdHkgfiBkaXJlY3Rpb246UGhlbm8uZGl2ZXJnZW5jZSArIFBoZW5vLmRpdmVyZ2VuY2UsDQojICAgIyBpZGgoU0UpOnVuaXRzIHwgd2VpZ2h0IGJ5IFNFIG9mIGVmZmVjdCBzaXplDQojICAgcmFuZG9tID0gfiBTdHVkeS5JRCArIENyb3NzLklEICsgc3BMLm5hbWUgKyBpZGgoU0UpOnVuaXRzLA0KIyAgIGZhbWlseSA9ICJjYXRlZ29yaWNhbCIsDQojICAgdmVyYm9zZSA9IEZBTFNFLA0KIyAgIGdpbnZlcnNlID0gbGlzdChzcEwubmFtZSA9IHBoeWxvX01DTUMpLA0KIyAgIHByaW9yID0gcHJpb3IsDQojICAgZGF0YSA9IHJhd2RhdCwNCiMgICBuaXR0ID0gNjAwMDAsICAjIEluY3JlYXNlIHRoZSBudW1iZXIgb2YgaXRlcmF0aW9ucywgZGVmYXVsdCBpcyAxMzAwMA0KIyAgIGJ1cm5pbiA9IDUwMDAgICMgSW5jcmVhc2UgdGhlIG51bWJlciBvZiBidXJuaW4sIGRlZmF1bHQgaXMgMzAwMA0KIyApDQojIHBoeWxtaXgkU29sIDwtIHBoeWxtaXgkU29sL3NxcnQoMStjMikNCiMgIyMgU2F2ZSBtb2RlbCAjIyMNCiMgc2F2ZVJEUyhwaHlsbWl4LCBmaWxlID0iLi4vQW5hbHlzaXMvTWVhbi5ub3ZlbHR5LlBoZW5vLmRpdmVyZ2VuY2Uub2JqIikNCg0KIysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrIw0KIyBQbG90DQojKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysjDQpmb3IgKGkgaW4gYygiR2VuZXQuZGl2ZXJnZW5jZSIsICJQaGVuby5kaXZlcmdlbmNlIikpIHsNCiAgDQogICMjIExvYWQgbW9kZWwgIyMjDQogIHBoeWxtaXggPC0gcmVhZFJEUygNCiAgICBwYXN0ZSgiLi4vQW5hbHlzaXMvTWVhbi5ub3ZlbHR5IixpLCAib2JqIiwgc2VwID0gIi4iKQ0KICAgICkNCiAgcmVnIDwtIHN1bW1hcnkocGh5bG1peCRTb2wpJHN0YXRpc3RpY3MgJT4lDQogICAgICBhcy5kYXRhLmZyYW1lKCkNCiAgDQogICMjIFBsb3QgIyMjDQogIHBsb3QgPC0gZ2dwbG90KHJhd2RhdCwgYWVzKHggPSByYXdkYXRbLGldLCB5ID0gcmF3ZGF0WywgIk5vdmVsdHkiXSkpICsNCiAgICBnZW9tX2ppdHRlcigNCiAgICAgIGhlaWdodCA9IDAuMSwgd2lkdGggPSAwLCBhZXMoY29sb3IgPSBkaXJlY3Rpb24pLCBhbHBoYSA9IDAuMywgc2l6ZSA9IDAuMg0KICAgICAgKSArDQogICAgIyBub3ZlbHR5IGZvciBsYXJnZXIgbWVhbg0KICAgIHN0YXRfZnVuY3Rpb24oDQogICAgICBhZXMoY29sb3IgPSAiKyIpLCBzaXplID0gMC44LA0KICAgICAgZnVuID0gZnVuY3Rpb24oeCkgDQogICAgICAgIDEvKDEgKyBleHAoLShyZWdbMSwxXSArIHgqKHJlZ1syLDFdK3JlZ1szLDFdKSkpKQ0KICAgICAgKSArDQogICAgIyBub3ZlbHR5IGZvciBzbWFsbGVyIG1lYW4NCiAgICBzdGF0X2Z1bmN0aW9uKA0KICAgICAgYWVzKGNvbG9yID0gIi0iKSwgc2l6ZSA9IDAuOCwNCiAgICAgIGZ1biA9IGZ1bmN0aW9uKHgpIA0KICAgICAgICAxLygxICsgZXhwKC0ocmVnWzEsMV0gKyB4KnJlZ1syLDFdKSkpDQogICAgICApICsNCiAgICB5bGFiKCJOb3ZlbHR5IGluIHBoZW5vdHlwaWMgbWVhbnMiKSArIA0KICAgIHhsYWIocGFzdGUoaSwgIihsb2cpIikpICsNCiAgICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDIiKSArDQogICAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcz1zZXEoMCwxKSkgKw0KICAgIHJlZ3Jlc3Npb250aGVtZSANCiAgcHJpbnQocGxvdCkNCiAgIyBnZ3NhdmUoDQogICMgICBwbG90ID0gcGxvdCArIHRoZW1lKGF4aXMudGl0bGUgID0gZWxlbWVudF9ibGFuaygpKSwNCiAgIyAgIGZpbGUgPSBwYXN0ZSgiLi4vQW5hbHlzaXMvbWVhbi5UUy5jb250aW51b3VzIiwgaSwgInN2ZyIsIHNlcCA9ICIuIiksDQogICMgICBoZWlnaHQgPSAxLjYsIHdpZHRoID0gMS43DQogICMgICApDQoNCn0NCg0KYGBgDQoNCmBgYHtyLCByZXN1bHRzPSdhc2lzJywgZmlnLmhlaWdodCA9IDMsIGZpZy53aWR0aCA9IDZ9DQoNCmZvciAoaSBpbiBjKCJSZWNpcHJvY2FsIiwgInRyYWl0LnR5cGUiKSkgew0KDQogICAgIyBNYWtlIG5ldyBjYXRlZ29yaWNhbCBkYXRhIGNvbWJpbmluZyBkaXJlY3Rpb24gb2YgVFMgYW5kIHRhcmdldCBjYXRlZ29yaWNhbCBmYWN0b3INCiAgICBkYXQgJTw+JQ0KICAgICAgbXV0YXRlKGludGVyYWN0aW9uID0gc3RyX2MoZGlyZWN0aW9uLCAuWywgaV0sIHNlcCA9ICJfIikpDQogICAgDQogICAgIyAjIyBTZXR0aW5nIHByaW9yIHRvIGxvZ2lzdGljIHJlZ3Jlc3Npb24gIyMjDQogICAgIyBwcmlvciA8LSBsaXN0KA0KICAgICMgICBCPWxpc3QoDQogICAgIyAgICAgbXUgPSByZXAoMCwgNCksICMgTiBvZiBjb2VmZmljaWVudC4gKGxldmVsIC0xKSBmb3IgY2F0ZWdvcmljYWwgZmFjdG9ycywgMSBmb3IgY29udGludW91cyBmYWN0b3JzLCAxIGZvciBpbnRlcmNlcHQNCiAgICAjICAgICBWID0gZ2VsbWFuLnByaW9yKH4gaW50ZXJhY3Rpb24sICMgKyB0cmFpdC5kaXJlY3Rpb24NCiAgICAjICAgICBkYXRhID0gZGF0LCAjIGZvcm11bGEgYW5kIGRhdGENCiAgICAjICAgICBzY2FsZT1zcXJ0KHBpXjIvMysxKSkpLCAjIGVycm9yIGRpc3RyaWJ1dGlvbiBvZiBsb2dpc3RpYyByZWdyZXNzaW9uDQogICAgIyAgIFI9bGlzdChWPTEsZml4PTEpLA0KICAgICMgICAjIFJlcGxpY2F0aW5nIHNhbWUgRyBmb3IgdGhlIG51bWJlciBvZiByYW5kb20gZWZmZWN0cyAoaGVyZSwgNCkNCiAgICAjICAgRyA9IGxpc3QoDQogICAgIyAgICAgRzEgPSBsaXN0KFYgPSAxLCBudSA9IDEsIGFscGhhLm11ID0gMCwgYWxwaGEuViA9IDEwMDApLA0KICAgICMgICAgIEcyID0gbGlzdChWID0gMSwgbnUgPSAxLCBhbHBoYS5tdSA9IDAsIGFscGhhLlYgPSAxMDAwKSwNCiAgICAjICAgICBHMyA9IGxpc3QoViA9IDEsIG51ID0gMSwgYWxwaGEubXUgPSAwLCBhbHBoYS5WID0gMTAwMCksDQogICAgIyAgICAgRzQgPSBsaXN0KFYgPSAxLCBudSA9IDEsIGFscGhhLm11ID0gMCwgYWxwaGEuViA9IDEwMDApDQogICAgIyAgICAgKQ0KICAgICMgICApDQogICAgIyANCiAgICAjIHBoeWxtaXggPC1NQ01DZ2xtbSgNCiAgICAjICAgZml4ZWQgPSBOb3ZlbHR5IH4gIGludGVyYWN0aW9uIC0xLCAjICsgdHJhaXQuZGlyZWN0aW9uDQogICAgIyAgIGZhbWlseSA9ICJjYXRlZ29yaWNhbCIsDQogICAgIyAgICMgaWRoKFNFKTp1bml0cyB8IHdlaWdodCBieSBTRSBvZiBlZmZlY3Qgc2l6ZQ0KICAgICMgICByYW5kb20gPSB+IFN0dWR5LklEICsgQ3Jvc3MuSUQgKyBzcEwubmFtZSArIGlkaChTRSk6dW5pdHMsDQogICAgIyAgIHZlcmJvc2UgPSBGQUxTRSwNCiAgICAjICAgZ2ludmVyc2UgPSBsaXN0KHNwTC5uYW1lID0gcGh5bG9fTUNNQyksDQogICAgIyAgIHByaW9yID0gcHJpb3IsDQogICAgIyAgIGRhdGEgPSBkYXQNCiAgICAjICkNCiAgICAjICMgQ29ycmVjdCBtb2RlbCByZXN1bHQNCiAgICAjIHBoeWxtaXgkU29sIDwtIHBoeWxtaXgkU29sL3NxcnQoMStjMikNCiAgICAjICMjIFNhdmUgbW9kZWwgIyMjDQogICAgIyBzYXZlUkRTKA0KICAgICMgICBwaHlsbWl4LA0KICAgICMgICBmaWxlID0NCiAgICAjICAgICBwYXN0ZSgiLi4vQW5hbHlzaXMvTWVhbi5ub3ZlbHR5IiwgaSwgImFsbHRheG9uLm9iaiIsIHNlcCA9ICIuIikNCiAgICAjICAgICApDQoNCiAgIysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrIyAgDQogICMgaW5nIGludGVyYWN0aW9uIHRlcm1zDQogICMrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyMNCiAgcGh5bG1peCA8LSByZWFkUkRTKA0KICAgIHBhc3RlKCIuLi9BbmFseXNpcy9NZWFuLm5vdmVsdHkiLCBpLCAiYWxsdGF4b24ub2JqIiwgc2VwID0gIi4iKQ0KICAgICkNCiAgDQogIHN1bSA8LSBzdW1tYXJ5KHBoeWxtaXgpJHNvbHV0aW9ucyAlPiUNCiAgICBhcy5kYXRhLmZyYW1lKCkgJT4lDQogICAgcm93bmFtZXNfdG9fY29sdW1uKHZhciA9ICJmYWN0b3JzIikgJT4lDQogICAgbXV0YXRlKA0KICAgICAgIyBJbXBhY3Qgb24gZXhjZWVkaW5nIHVwcGVyIG9yIGxvd2VyIHJhbmdlDQogICAgICBkaXJlY3Rpb24gPQ0KICAgICAgICBpZmVsc2Uoc3RyX2RldGVjdChmYWN0b3JzLCAiaW50ZXJhY3Rpb25cXCsiKSwgDQogICAgICAgICAgICAgICAiRXhjZWVkIHVwcGVyIHJhbmdlIiwNCiAgICAgICAgICAgICAgICJFeGNlZWQgbG93ZXIgcmFuZ2UiDQogICAgICAgICAgICAgICApICU+JQ0KICAgICAgICBhcy5mYWN0b3INCiAgICAgICkgJT4lDQogICAgd2l0aGluKGRpcmVjdGlvbiA8LSBvcmRlcmVkKGRpcmVjdGlvbiwgYygiRXhjZWVkIHVwcGVyIHJhbmdlIiwgIkV4Y2VlZCBsb3dlciByYW5nZSIpKSkgJT4lDQogICAgIyMgQ2hhbmdlIGZhY3RvciBuYW1lcyAjIyMNCiAgICB3aXRoaW4oDQogICAgICBmYWN0b3JzIDwtIHN0cl9yZW1vdmVfYWxsKGZhY3RvcnMsICJpbnRlcmFjdGlvbi5fIikNCiAgICAgICkgICAgICAgDQogIA0KICAgICMrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyMgIA0KICAgICMgUGxvdA0KICAgICMrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyMNCiAgICBjYXRlZ29yaWNhbHBsb3QgPC0gZ2dwbG90KHN1bSwgYWVzKHggPSBwb3N0Lm1lYW4sIHkgPSBmYWN0b3JzKSkgKw0KICAgICAgIyBWZXJ0aWNhbCBsaW5lDQogICAgICBnZW9tX3ZsaW5lKA0KICAgICAgICB4aW50ZXJjZXB0ID0gMCwgc2l6ZSA9IDAuMywNCiAgICAgICAgY29sb3VyID0gImdyZXkzMCIsIGxpbmV0eXBlID0gImRvdHRlZCINCiAgICAgICAgKSArDQogICAgICAjIENJDQogICAgICBnZW9tX2Vycm9yYmFyaCgNCiAgICAgICAgYWVzKHhtaW4gPSBzdW1bLCAnbC05NSUgQ0knXSwgeG1heCA9IHN1bVssICd1LTk1JSBDSSddKSwNCiAgICAgICAgaGVpZ2h0ID0gLjAwMDENCiAgICAgICAgKSArDQogICAgICBnZW9tX3BvaW50KHNpemUgPSAxLjMsIHNoYXBlID0gMTcpICsNCiAgICAgICMgVGl0bGUNCiAgICAgIHlsYWIoIiIpICsgeGxhYigiRWZmZWN0IG9uIG5vdmVsdHkgaW4gcGhlbm90eXBpYyBtZWFucyIpICsNCiAgICAgIGdndGl0bGUoaSkgKw0KICAgICAgIyBDb21iaW5lIGRpZmZlcmVudCBwbG90cyBmb3IgbWFpbiBmYWN0b3JzIGFuZCBpbnRlcmFjdGlvbnMNCiAgICAgIGZhY2V0X2dyaWQoDQogICAgICAgIGRpcmVjdGlvbiB+Liwgc2NhbGVzID0gImZyZWUiLCBkcm9wID0gVFJVRSwNCiAgICAgICAgbGFiZWxsZXIgPSBsYWJlbF93cmFwX2dlbih3aWR0aCA9IDExKQ0KICAgICAgICApICsNCiAgICAgIGZvcmVzdHRoZW1lDQogICAgcHJpbnQoY2F0ZWdvcmljYWxwbG90KQ0KICANCiAgICAjIGdnc2F2ZSgNCiAgICAjICAgICBwbG90ID0gY2F0ZWdvcmljYWxwbG90ICsgdGhlbWUoYXhpcy50ZXh0LnkgPSBlbGVtZW50X2JsYW5rKCkpLA0KICAgICMgICAgIGZpbGUgPSBwYXN0ZSgiLi4vQW5hbHlzaXMvTWVhbi5UUy5jYXRlZ29yaWNhbCIsIGksdGF4b24sICJzdmciLCBzZXAgPSAiLiIpLA0KICAgICMgICAgIGhlaWdodCA9IDEuOCwgd2lkdGggPSAyLjUNCiAgICAjICAgICApDQoNCn0NCg0KYGBgDQoNCg0KDQoNCjxkaXYgc3R5bGU9Im1hcmdpbi1ib3R0b206MTgwcHg7Ij4NCjwvZGl2Pg0KIyBOb3ZlbHR5IGluIHBoZW5vdHlwaWMgdmFyaWFiaWxpdGllcyAodXNpbmcgQ1YpDQoNCiMjIEZyZXF1ZW5jeQ0KDQpgYGB7cn0NCg0KZGF0LmZ1bGwgPC0gcmVhZC5jc3YoIi4uL2RhdGEvdmFyaWF0aW9uLkVTLk5vdmVsdHkuY3N2IiwgaGVhZCA9IFRSVUUpDQoNCiMjIE4gb2YgVFMgaW4gZWFjaCB0YXhhIGFuZCBlYWNoIGRpcmVjdGlvbiAjIyMNCnN1bW1hcnkgPC0gYmluZF9yb3dzKA0KICAjIEFsbCBvYnNlcnZhdGlvbnMNCiAgZGF0LmZ1bGwgJT4lDQogICAgZ3JvdXBfYnkodGF4YSkgJT4lDQogICAgc3VtbWFyaXNlKA0KICAgICAgJ1NwZWNpZXMgcGFpcicgPSBsZW5ndGgodW5pcXVlKHNwZWNpZXMucGFpcikpLA0KICAgICAgT2JzZXJ2YXRpb25zID0gbGVuZ3RoKHVuaXF1ZShFUy5JRCkpLA0KICAgICAgU3R1ZHkgPSBsZW5ndGgodW5pcXVlKFN0dWR5LklEKSkNCiAgICAgICkgJT4lDQogICAgbXV0YXRlKGRpcmVjdGlvbiA9ICJBbGwgT2JzZXJ2YXRpb25zIikNCiAgLA0KICAjIFRTIGZvciBhbnkgZGlyZWN0aW9uDQogIGRhdC5mdWxsICU+JQ0KICAgIGZpbHRlcihOb3ZlbHR5ID09ICIxIikgJT4lDQogICAgZ3JvdXBfYnkodGF4YSkgJT4lDQogICAgc3VtbWFyaXNlKA0KICAgICAgJ1NwZWNpZXMgcGFpcicgPSBsZW5ndGgodW5pcXVlKHNwZWNpZXMucGFpcikpLA0KICAgICAgT2JzZXJ2YXRpb25zID0gbGVuZ3RoKHVuaXF1ZShFUy5JRCkpLA0KICAgICAgU3R1ZHkgPSBsZW5ndGgodW5pcXVlKFN0dWR5LklEKSkNCiAgICAgICkgJT4lDQogICAgbXV0YXRlKGRpcmVjdGlvbiA9ICJJbmNyZWFzZSBub3ZlbHR5IikNCiAgLA0KICAjIFRTIGZvciBlYWNoIGRpcmVjdGlvbg0KICBkYXQuZnVsbCAlPiUNCiAgICBmaWx0ZXIoTm92ZWx0eSA9PSAiMSIpICU+JQ0KICAgIGdyb3VwX2J5KHRheGEsIGRpcmVjdGlvbikgJT4lDQogICAgc3VtbWFyaXNlKA0KICAgICAgJ1NwZWNpZXMgcGFpcicgPSBsZW5ndGgodW5pcXVlKHNwZWNpZXMucGFpcikpLA0KICAgICAgT2JzZXJ2YXRpb25zID0gbGVuZ3RoKHVuaXF1ZShFUy5JRCkpLA0KICAgICAgU3R1ZHkgPSBsZW5ndGgodW5pcXVlKFN0dWR5LklEKSkNCiAgICAgICkNCiAgKSAlPiUNCiAgIyBBc3NpZ24gMCBmb3Igbm8gb2JzZXJ2YXRpb24gb2YgVFMNCiAgcmVwbGFjZSguLCBpcy5uYSguKSwgIjAiKSAlPiUgDQogICMgTWFrZSB0aWR5IGRhdGENCiAgZ2F0aGVyKGtleSA9IG1ldHJpY3MsIHZhbHVlID0gTiwgLWModGF4YSwgZGlyZWN0aW9uKSkgJT4lDQogICMgT3JkZXIgZmFjdG9ycw0KICBtdXRhdGVfYXQodmFycygibWV0cmljcyIsICJkaXJlY3Rpb24iKSwgYXMuZmFjdG9yKSAlPiUNCiAgZmlsdGVyKG1ldHJpY3MgIT0gIlN0dWR5IikNCg0KIyBPcmRlciB0YXhvbg0Kc3VtbWFyeSRtZXRyaWNzIDwtIG9yZGVyZWQoc3VtbWFyeSRtZXRyaWNzLCBsZXZlbHMgPSBjKCJTdHVkeSIsICJTcGVjaWVzIHBhaXIiLCAiT2JzZXJ2YXRpb25zIikpDQojIE9yZGVyIFRTIGNhdGVnb3J5DQpzdW1tYXJ5JGRpcmVjdGlvbiA8LSBvcmRlcmVkKHN1bW1hcnkkZGlyZWN0aW9uLCBsZXZlbHMgPSBjKCJBbGwgT2JzZXJ2YXRpb25zIiwgIkluY3JlYXNlIG5vdmVsdHkiLCAiKyIsICItIikpDQojIENoYW5nZSBuYW1lcyBvZiBUUyBjYXRlZ29yeSB0byBtb3JlIGludHVpdGl2ZSBuYW1lDQpsZXZlbHMoc3VtbWFyeSRkaXJlY3Rpb24pIDwtIGMoIkFsbCBPYnNlcnZhdGlvbnMiLCAiSW5jcmVhc2Ugbm92ZWx0eSIsICJFeGNlZWQgdXBwZXIgcmFuZ2UiLCAiRXhjZWVkIGxvd2VyIHJhbmdlIikNCg0KIyMgUGxvdCAjIyMNCnBsb3QgPC0gZ2dwbG90KA0KICAjIHJlbmFtZSBsZXZlbHMgb2YgZmFjdG9ycyB0byB3cmFwIGxhYmVsIHRleHQNCiAgc3VtbWFyeSAlPiUNCiAgICB3aXRoaW4obGV2ZWxzKGRpcmVjdGlvbikgPC0gYygiQWxsIE9ic2VyLSB2YXRpb25zIiwgIk5vdmVsIHBoZW5vdHlwaWMgdmFyaWFiaWxpdGllcyIsICJFeGNlZWQgdXBwZXIgcmFuZ2UiLCAiRXhjZWVkIGxvd2VyIHJhbmdlIikpICU+JQ0KICAgIHdpdGhpbihsZXZlbHMobWV0cmljcykgPC0gYygiU3R1ZHkiLCAiU3BlY2llcyBwYWlyIiwgIk9ic2VyLSB2YXRpb25zIikpLCANCiAgYWVzKHggPSAiIiwgeSA9IE4sIGZpbGwgPSB0YXhhKSkgKw0KICBnZW9tX2Jhcih3aWR0aCA9IDEsIHN0YXQgPSAiaWRlbnRpdHkiKSArDQogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiUGFpcmVkIikgKw0KICBmYWNldF9ncmlkKA0KICAgIHNjYWxlID0gImZyZWUiLCBtZXRyaWNzIH4gZGlyZWN0aW9uLA0KICAgICMgc3RyaXAgdGV4dCBpbnRvIHR3byBsaW5lcw0KICAgIGxhYmVsbGVyID0gbGFiZWxfd3JhcF9nZW4od2lkdGggPSAxMCkNCiAgICApICsNCiAgeGxhYigiIikgKyB5bGFiKCIiKSArDQogIHN0YWNrZWRiYXJ0aGVtZQ0KcGxvdCArDQogIGdndGl0bGUoIlRheG9ub21pYyBkaXN0cmlidXRpb24gb2Ygbm92ZWwgcGhlbm90eXBpYyB2YXJpYWJpbGl0aWVzIikNCg0KIyBnZ3NhdmUoDQojICAgcGxvdCA9IHBsb3QsDQojICAgZmlsZSA9ICIuLi9BbmFseXNpcy9WYXJpYXRpb24uVFMuZnJlcXVlbmN5LnN2ZyIsIGhlaWdodCA9IDMuNywgd2lkdGggPSA1LjANCiMgICApDQoNCiMjIFRvdGFsIG51bWJlciBvZiBvYnNlcnZhdGlvbnMgYW5kIHBlcmNlbnRhZ2UgIyMjDQpzdW1tYXJ5ICU+JQ0KICBncm91cF9ieShkaXJlY3Rpb24sIG1ldHJpY3MpICU+JQ0KICAjIENvdW50IG51bWJlciBvZiBvYnNlcnZhaXRvbnMgYW5kIHNwZWNpZXMgcGFpcnMNCiAgc3VtbWFyaXNlKHN1bShOKSkgJT4lDQogIHNwcmVhZChrZXkgPSBtZXRyaWNzLCB2YWx1ZSA9ICJzdW0oTikiKSAlPiUNCiAgYXMuZGF0YS5mcmFtZSgpICU+JQ0KICAjIENhbGN1bGF0ZSBwZXJjZW50YWdlDQogIG11dGF0ZSgNCiAgICAnU3BlY2llcyBwYWlyICUnID0gLlssICJTcGVjaWVzIHBhaXIiXS8uWzEsICJTcGVjaWVzIHBhaXIiXSoxMDAsDQogICAgJ09ic2VydmF0b24gJScgPSBPYnNlcnZhdGlvbnMvLlsxLCAiT2JzZXJ2YXRpb25zIl0qMTAwDQogICkgJT4lDQogIG11dGF0ZV9hdCh2YXJzKGNvbnRhaW5zKCJwZXJjZW50IikpLCByb3VuZCwgMikgJT4lDQogIGthYmxlKCJodG1sIiwgZGlnaXRzID0gMywgY2FwdGlvbiA9ICJTdW1tYXJ5IG9mIHRoZSBub3ZlbCBwaGVub3R5cGljIHZhcmlhYmlsaXRpZXMgZnJlcXVlbmN5IikgJT4lIA0KICBrYWJsZV9zdHlsaW5nKCJzdHJpcGVkIiwgcG9zaXRpb24gPSAibGVmdCIpDQoNCmBgYA0KDQo8ZGl2IHN0eWxlPSJtYXJnaW4tYm90dG9tOjcwcHg7Ij4NCjwvZGl2Pg0KDQojIyBGYWN0b3JzIGFmZmVjdGluZyAgbm92ZWx0eSBpbiBwaGVub3R5cGljIHZhcmlhYmlsaXR5DQpXZSBjaGVja2VkIHJvYnVzdG5lc3Mgb2YgcmVzdWx0cyBieSBjb25kdWN0aW5nIGlkZW50aWNhbCBhbmFseXNpcyBmb3IgYGluc2VjdGAgc3Vic2V0IGRhdGEgKHJlbW92aW5nIHZlcnRlYnJhdGUgZGF0YSkuIDxicj4NCg0KTW9kZWwsIHdoaWNoIHdhcyByYW4gdXNpbmcgYE1DTUNnbG1tYCBmdW5jdGlvbiwgaW5jbHVkZWQgZm9sbG93aW5nIFJhbmRvbSBlZmZlY3RzIGVzdGltYXRlczogDQoNCiogYFN0dWR5LklEYDogUHJpbWFyeSBzdHVkaWVzDQoNCiogYENyb3NzLklEYDogUGFyZW50YWwgc3RyYWluIHVzZWQgaW4gdGhlIGNyb3NzaW5nLiBEaXNjcmltaW5hdGUgaW50cmFzcGVjaWZpYyBwb3B1bGF0aW9ucw0KDQoqIGBzcEwubmFtZWA6IFBoeWxvZ2VueSBvZiBwYXJlbnRhbCBzcGVjaWVzICg8aT5zcExMPHN1Yj5WPC9zdWI+PC9pPikNCg0KKiBgU0UudW5pdHNgOiBTYW1wbGluZyB2YXJpYW5jZSBvZiBlZmZlY3Qgc2l6ZQ0KDQpUaGUgbW9kZXJhdG9ycyB3ZXJlIGNhdGVnb3Jpc2VkIGludG8gMyBzdWJzZXRzOiBtYWluIGVmZmVjdHMgKGxhYmVsbGVkIGFzIGBub3ZlbHR5IGluIHBoZW5vdHlwaWMgdmFyaWFiaWxpdGllc2ApLCBpbnRlcmFjdGlvbiB0ZXJtcyB3aXRoIGNvbXBhcmVkIHBhcmVudGFsIHNwZWNpZXMgKHNwTEwgdnMuIHNwU1MsIGxhYmVsbGVkIGFzIGBleGNlZWQgdXBwZXIgcmFuZ2VgOyBtb3RoZXIgc3BlY2llcyB2cy4gZmF0aGVyLCBsYWJlbGxlZCBhcyBgZXhjZWVkIG1vdGhlcmApLiANCg0KYGBge3IsIHJlc3VsdHM9J2FzaXMnfQ0KDQojKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyMNCiMgUGh5bG9nZW5ldGljIHRyZWUgZm9yIG1jbWNnbG1tIA0KIysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysjDQoNCiMgY29tcHV0ZSBicmFuY2ggbGVuZ3RocyBvZiB0cmVlDQpwaHlsb19icmFuY2ggPC0gcmVhZC50cmVlKGZpbGUgPSAiLi4vZGF0YS9waHlsby52YXJpYXRpb24udHJlIikgJT4lDQogIGNvbXB1dGUuYnJsZW4obWV0aG9kID0gIkdyYWZlbiIsIHBvd2VyID0gMSkNCg0KIyBzYXZpbmcgcGh5bG9nZW5laWMgbWF0cml4DQpwaHlsb19jb3IgPC0gdmN2KHBoeWxvX2JyYW5jaCwgY29yID0gVCkNCg0KIyBnZW5lcmF0aW5nIGludmVyc2UgcGh5bG9nZW5ldGljIG1hdHJpeCBmb3IgTUNNQ2dsbW0NCnBoeWxvX2JyYW5jaCRub2RlLmxhYmVsIDwtIE5VTEwNCnBoeWxvX01DTUMgPC0gTUNNQ2dsbW06OmludmVyc2VBKHBoeWxvX2JyYW5jaCwgbm9kZXMgPSAiQUxMIiwgc2NhbGUgPSBUUlVFKSRBaW52DQoNCg0KIysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysjDQojIFBoeWxvZ2VuZXRpYyBjb21wYXJhdGl2ZSBhbmFseXNpcw0KIysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysjDQoNCiMgQ2FwdGlvbg0KY2FwIDwtIGRhdGEuZnJhbWUoDQogIGRlc2MgPSBjKA0KICAgICJUYWJsZSBTOC4gRml4ZWQgZWZmZWN0cyBlc3RpbWF0ZXMgb2YgQmF5ZXNpYW4gbG9naXN0aWMgbW9kZWwgaW52ZXN0aWdhdGluZyBmYWN0b3JzIGFmZmVjdGluZyBub3ZlbHR5IGluIHBoZW5vdHlwaWMgdmFyaWFiaWxpdGllcy4gRGF0YSBvZiBhbGwgdGF4b24gd2FzIHVzZWQiLA0KICAgICJGaXhlZCBlZmZlY3RzIGVzdGltYXRlczogaW5zZWN0IHN1YnNldCBkYXRhIg0KICAgICkNCiAgKSAlPiUNCiAgbXV0YXRlX2FsbChhcy5jaGFyYWN0ZXIpDQpyb3cubmFtZXMoY2FwKSA8LSBjKCJhbGx0YXhvbiIsICJpbnNlY3QiKQ0KDQpmb3IgKHRheG9uIGluIGMoImFsbHRheG9uIiwgImluc2VjdCIpKSB7DQogIA0KICBpZiAodGF4b24gPT0gImFsbHRheG9uIikgew0KICAgIGRhdCA8LSBkYXQuZnVsbA0KICB9IGVsc2Ugew0KICAgIGRhdCA8LSBkYXQuZnVsbCAlPiUgDQogICAgICBmaWx0ZXIoaW5zZWN0ID09IHRheG9uKQ0KICB9DQogIA0KICAjICMjIFNldHRpbmcgcHJpb3IgdG8gbG9naXN0aWMgcmVncmVzc2lvbiAjIyMNCiAgIyBwcmlvciA8LSBsaXN0KA0KICAjICAgQj1saXN0KA0KICAjICAgICBtdSA9IHJlcCgwLCAxNyksICMgTiBvZiBjb2VmZmljaWVudC4gKGxldmVsIC0xKSBmb3IgY2F0ZWdvcmljYWwgZmFjdG9ycywgMSBmb3IgY29udGludW91cyBmYWN0b3JzLCAxIGZvciBpbnRlcmNlcHQNCiAgIyAgICAgViA9IGdlbG1hbi5wcmlvcih+DQogICMgICAgIHBhcmVudGFsKkhldGVyby5zZXggKyBwYXJlbnRhbCpkaXJlY3Rpb24gKw0KICAjICAgICBkaXJlY3Rpb24qR2VuZXQuZGl2ZXJnZW5jZSArIGRpcmVjdGlvbipQaGVuby5kaXZlcmdlbmNlICsNCiAgIyAgICAgZGlyZWN0aW9uKkhldGVyby5zZXggKyBkaXJlY3Rpb24qdHJhaXQudHlwZSArDQogICMgICAgIGRpcmVjdGlvbipEaXN0cmlidXRpb24gKyBkaXJlY3Rpb24qUmVjaXByb2NhbCwNCiAgIyAgICAgZGF0YSA9IGRhdCwgIyBmb3JtdWxhIGFuZCBkYXRhDQogICMgICAgIHNjYWxlPXNxcnQocGleMi8zKzEpKSksICMgZXJyb3IgZGlzdHJpYnV0aW9uIG9mIGxvZ2lzdGljIHJlZ3Jlc3Npb24NCiAgIyAgIFI9bGlzdChWPTEsZml4PTEpLA0KICAjICAgIyBSZXBsaWNhdGluZyBzYW1lIEcgZm9yIHRoZSBudW1iZXIgb2YgcmFuZG9tIGVmZmVjdHMgKGhlcmUsIDQpDQogICMgICBHID0gbGlzdCgNCiAgIyAgICAgRzEgPSBsaXN0KFYgPSAxLCBudSA9IDEsIGFscGhhLm11ID0gMCwgYWxwaGEuViA9IDEwMDApLA0KICAjICAgICBHMiA9IGxpc3QoViA9IDEsIG51ID0gMSwgYWxwaGEubXUgPSAwLCBhbHBoYS5WID0gMTAwMCksDQogICMgICAgIEczID0gbGlzdChWID0gMSwgbnUgPSAxLCBhbHBoYS5tdSA9IDAsIGFscGhhLlYgPSAxMDAwKSwNCiAgIyAgICAgRzQgPSBsaXN0KFYgPSAxLCBudSA9IDEsIGFscGhhLm11ID0gMCwgYWxwaGEuViA9IDEwMDApDQogICMgICAgICkNCiAgIyAgICkNCiAgIyAjIyBQaHlsb2dlbmV0aWMgYmlub21pYWwgcmVncmVzc2lvbiAjIyMNCiAgIyBwaHlsbWl4IDwtTUNNQ2dsbW0oDQogICMgICBmaXhlZCA9IE5vdmVsdHkgfg0KICAjICAgICBwYXJlbnRhbCpIZXRlcm8uc2V4ICsgcGFyZW50YWwqZGlyZWN0aW9uICsNCiAgIyAgICAgZGlyZWN0aW9uKkdlbmV0LmRpdmVyZ2VuY2UgKyBkaXJlY3Rpb24qUGhlbm8uZGl2ZXJnZW5jZSArDQogICMgICAgIGRpcmVjdGlvbipIZXRlcm8uc2V4ICsgZGlyZWN0aW9uKnRyYWl0LnR5cGUgKw0KICAjICAgICBkaXJlY3Rpb24qRGlzdHJpYnV0aW9uICsgZGlyZWN0aW9uKlJlY2lwcm9jYWwsDQogICMgICBmYW1pbHkgPSAiY2F0ZWdvcmljYWwiLA0KICAjICAgIyBpZGgoU0UpOnVuaXRzIHwgd2VpZ2h0IGJ5IFNFIG9mIGVmZmVjdCBzaXplDQogICMgICByYW5kb20gPSB+IFN0dWR5LklEICsgQ3Jvc3MuSUQgKyBzcEwubmFtZSArIGlkaChTRSk6dW5pdHMsDQogICMgICB2ZXJib3NlID0gRkFMU0UsDQogICMgICBnaW52ZXJzZSA9IGxpc3Qoc3BMLm5hbWUgPSBwaHlsb19NQ01DKSwNCiAgIyAgIHByaW9yID0gcHJpb3IsDQogICMgICBkYXRhID0gZGF0LA0KICAjICAgbml0dCA9IDYwMDAwLCAgIyBJbmNyZWFzZSB0aGUgbnVtYmVyIG9mIGl0ZXJhdGlvbnMsIGRlZmF1bHQgaXMgMTMwMDANCiAgIyAgIGJ1cm5pbiA9IDUwMDAgICMgSW5jcmVhc2UgdGhlIG51bWJlciBvZiBidXJuaW4sIGRlZmF1bHQgaXMgMzAwMA0KICAjICkNCiAgIyAjIyBDb3JyZWN0aW5nIGVzdGltYXRlICMjIw0KICAjIHBoeWxtaXgkU29sIDwtIHBoeWxtaXgkU29sL3NxcnQoMStjMikNCiAgIyAjIyBTYXZlIG1vZGVsICMjIw0KICAjIHNhdmVSRFMoDQogICMgICBwaHlsbWl4LA0KICAjICAgZmlsZSA9IHBhc3RlKCIuLi9BbmFseXNpcy9WYXJpYXRpb24ubm92ZWx0eS5hbGxmYWN0b3JzIiwgdGF4b24sICJvYmoiLCBzZXAgPSAiLiIpDQogICMgICApDQogIA0KICAjIyBMb2FkIG1vZGVsICMjIw0KICBwaHlsbWl4IDwtIHJlYWRSRFMoZmlsZSA9IHBhc3RlKCIuLi9BbmFseXNpcy9WYXJpYXRpb24ubm92ZWx0eS5hbGxmYWN0b3JzIiwgdGF4b24sICJvYmoiLCBzZXAgPSAiLiIpKQ0KICANCiAgc3VtIDwtIGdldF9maXhlZC5NQ01DZ2xtbShzdW1tYXJ5KHBoeWxtaXgpJHNvbHV0aW9ucykgJT4lDQogICAgIyMgaW5nIEZhY3RvcnMgIyMjDQogICAgbXV0YXRlKA0KICAgICAgR3JvdXAgPSANCiAgICAgICAgaWZlbHNlKHN0cl9kZXRlY3QoRmFjdG9ycywgImRpcmVjdGlvbi46IiksIA0KICAgICAgICAgICAgICAgIkV4Y2VlZCB1cHBlciByYW5nZSIsDQogICAgICAgICAgICAgICBpZmVsc2Uoc3RyX2RldGVjdChGYWN0b3JzLCAicGFyZW50YWxNb3RoZXI6IiksDQogICAgICAgICAgICAgICAgICAgICAgIkV4Y2VlZCBtb3RoZXIiLA0KICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShGYWN0b3JzID09ICJIZXRlcm8uc2V4TWFsZTpkaXJlY3Rpb24rIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkV4Y2VlZCB1cHBlciByYW5nZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJJbmNyZWFzZSBub3ZlbHR5Ig0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICAgKQ0KICAgICAgICAgICAgICAgKQ0KICAgICkgJT4lDQogICAgbXV0YXRlX2F0KCJHcm91cCIsIGFzLmZhY3RvcikgJT4lDQogICAgd2l0aGluKEdyb3VwIDwtIG9yZGVyZWQoR3JvdXAsIGMoIkluY3JlYXNlIG5vdmVsdHkiLCAiRXhjZWVkIHVwcGVyIHJhbmdlIiwgIkV4Y2VlZCBtb3RoZXIiKSkpICU+JQ0KICAgICMjIENoYW5nZSBmYWN0b3IgbmFtZXMgIyMjDQogICAgd2l0aGluKA0KICAgICAgRmFjdG9ycyA8LSBzdHJfcmVtb3ZlX2FsbCgNCiAgICAgICAgRmFjdG9ycywgImRpcmVjdGlvbi46Ig0KICAgICAgICApICU+JQ0KICAgICAgICBzdHJfcmVtb3ZlX2FsbCguLCAicGFyZW50YWxNb3RoZXI6IikgJT4lDQogICAgICAgIHN0cl9yZW1vdmVfYWxsKC4sICI6ZGlyZWN0aW9uLiIpDQogICAgICApICU+JQ0KICAgIHdpdGhpbigNCiAgICAgIEZhY3RvcnMgPC0gZmFjdG9yKA0KICAgICAgICBGYWN0b3JzLCBvcmRlcmVkID0gVFJVRSwgDQogICAgICAgIGxldmVscyA9IGMoInBhcmVudGFsTW90aGVyIiwgImRpcmVjdGlvbisiLCAidHJhaXQudHlwZXNvdW5kIiwgIkhldGVyby5zZXhNYWxlIiwgIlJlY2lwcm9jYWxWaWFibGUiLCAiRGlzdHJpYnV0aW9uT3ZlcmxhcCIsICJQaGVuby5kaXZlcmdlbmNlIiwgICJHZW5ldC5kaXZlcmdlbmNlIiwgICIoSW50ZXJjZXB0KSIpDQogICAgICAgICkNCiAgICAgICkNCiAgbGV2ZWxzKHN1bSRGYWN0b3JzKSA8LSBjKCJFeGNlZWQgbW90aGVyIiwgIkV4Y2VlZCB1cHBlciByYW5nZSIsICJTb3VuZCB0cmFpdHMiLCAiTWFsZSBoZXRlcm9nYW1ldGljIiwgIlZpYWJsZSByZWNpcHJvY2FsIGh5YnJpZHMiLCAiRGlzdHJpYnV0aW9uIG92ZXJsYXAiLCAiUGhlbm90eXBpYyBkaXZlcmdlbmNlIiwgIkdlbmV0aWMgZGl2ZXJnZW5jZSIsICJJbnRlcmNlcHQiKQ0KICANCiAgIyMgUGxvdCAjIyMNCiAgbWV0YXBsb3QgPC0gZ2dwbG90KHN1bSwgYWVzKHggPSBwb3N0Lm1lYW4sIHkgPSBGYWN0b3JzKSkgKw0KICAgICMgVmVydGljYWwgbGluZQ0KICAgIGdlb21fdmxpbmUoDQogICAgICB4aW50ZXJjZXB0ID0gMCwgc2l6ZSA9IDAuMiwgDQogICAgICBjb2xvdXIgPSAiZ3JleTMwIiwgbGluZXR5cGUgPSAiZG90dGVkIiAgICAgICAgIA0KICAgICAgKSArDQogICAgIyBDSQ0KICAgIGdlb21fZXJyb3JiYXJoKA0KICAgICAgYWVzKA0KICAgICAgICB4bWluID0gc3VtWywgJ2wtOTUlIENJJ10sIHhtYXggPSBzdW1bLCAndS05NSUgQ0knXSwNCiAgICAgICAgY29sb3VyPXNpZ25pZmljYW5jZSANCiAgICAgICAgKSwgDQogICAgICBoZWlnaHQgPSAuMDAwMQ0KICAgICAgKSArDQogICAgIyBDb2xvciBvZiBwbG90cyBhbmQgZXJyb3JiYXJzDQogICAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKCJncmV5NjAiLCAiYmxhY2siKSkgKw0KICAgIGdlb21fcG9pbnQoc2l6ZSA9IDEsIGFlcyhjb2xvdXIgPSBzaWduaWZpY2FuY2UpKSArDQogICAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiZ3JleTYwIiwgImJsYWNrIikpICsNCiAgICAjIFRpdGxlDQogICAgZ2d0aXRsZShwYXN0ZSgiRml4ZWQgZWZmZWN0cyBlc3RpbWF0ZXMgdXNpbmciLCB0YXhvbiwgImRhdGEiKSkgKw0KICAgIHlsYWIoIiIpICsgeGxhYigiRXN0aW1hdGUgd2l0aCA5NSUgQ0kiKSArDQogICAgIyBDb21iaW5lIGRpZmZlcmVudCBwbG90cyBmb3IgbWFpbiBGYWN0b3JzIGFuZCBpbnRlcmFjdGlvbnMNCiAgICBmYWNldF9ncmlkKA0KICAgICAgR3JvdXB+Liwgc2NhbGVzID0gImZyZWUiLCBzcGFjZSA9ICJmcmVlIiwNCiAgICAgIGxhYmVsbGVyID0gbGFiZWxfd3JhcF9nZW4od2lkdGggPSAyMCkNCiAgICAgICkgKw0KICAgICMgVGhlbWVzDQogICAgZm9yZXN0dGhlbWUNCiAgcHJpbnQobWV0YXBsb3QpDQogIA0KICAjIGdnc2F2ZSgNCiAgIyAgICAgcGxvdCA9IG1ldGFwbG90LCANCiAgIyAgICAgZmlsZSA9IHBhc3RlKCIuLi9BbmFseXNpcy92YXJpYXRpb24uVFMucmVzdWx0IiwgdGF4b24sICJzdmciLCBzZXAgPSAiLiIpLCANCiAgIyAgICAgaGVpZ2h0ID0gNC43LCB3aWR0aCA9IDQuMA0KICAjICAgICApDQogIA0KICAjKysrKysrKysrKysrKysrKysrKysrKysrKyMNCiAgIyBGaXhlZCBlZmZlY3RzIG91dHB1dA0KICAjKysrKysrKysrKysrKysrKysrKysrKysrKyMNCiAgc3VtICU+JSANCiAgICBzZWxlY3QoR3JvdXAsIEZhY3RvcnMsIEVzdGltYXRlcywgJzk1JSBjcmVkaWJsZSBpbnRlcnZhbCcsIFAsIHNpZ25pZmljYW5jZSwgRGVzY3JpcHRpb24pICU+JQ0KICAgIGthYmxlKCJodG1sIiwgY2FwdGlvbiA9IGNhcFt0YXhvbixdKSAlPiUgDQogICAga2FibGVfc3R5bGluZygic3RyaXBlZCIsIHBvc2l0aW9uID0gImxlZnQiKSAlPiUNCiAgICBzY3JvbGxfYm94KHdpZHRoID0gIjEwMCUiLCBoZWlnaHQgPSAiNTAwcHgiKSAlPiUNCiAgICBwcmludCgpDQogIA0KICAjKysrKysrKysrKysrKysrKysrKysrKysrKysrIw0KICAjIFJhbmRvbSBlZmZlY3RzIG91dHB1dCANCiAgIysrKysrKysrKysrKysrKysrKysrKysrKysrKyMNCiAgIyB0cmFuc2Zvcm1hdGlvbiBmb3IgdmFyYWluY2UNCiAgZ2V0X3JhbmRvbS5NQ01DZ2xtbShzdW1tYXJ5KHBoeWxtaXgkVkNWLygxK2MyKSkpICU+JQ0KICAgIGthYmxlKCJodG1sIiwgZGlnaXRzID0gMiwNCiAgICAgICAgICBjYXB0aW9uID0gcGFzdGUoIlJhbmRvbSBlZmZlY3RzIGVzdGltYXRlczogIiwgdGF4b24sICJkYXRhIiwgIiAiKQ0KICAgICAgICAgICkgJT4lIA0KICAgIGthYmxlX3N0eWxpbmcoInN0cmlwZWQiLCBwb3NpdGlvbiA9ICJsZWZ0IikgJT4lDQogICAgcHJpbnQoKQ0KICANCn0NCg0KYGBgDQpXaGlsZSBzaWduaWZpY2FudCBtb2RlcmF0b3JzIGJlY29tZSBubyBsb25nZXIgc2lnbmlmaWNhbnQgaW4gYGluc2VjdGAgc3Vic2V0IGRhdGEsIGVmZmVjdHMgYXJlIHF1YWxpdGF0aXZlbHkgdGhlIHNhbWUgaW4gc2lnbi4gIA0KDQo8ZGl2IHN0eWxlPSJtYXJnaW4tYm90dG9tOjcwcHg7Ij4NCjwvZGl2Pg0KDQojIyBFZmZlY3RzIG9mIHNpZ25pZmljYW50IG1vZGVyYXRvcnMgDQpUbyB2aXN1YWxseSBpbnRlcnByZXQgdGhlIGltcGFjdHMgb2Ygc2lnbmlmaWNhbnQgbW9kZXJhdG9ycywgd2UgYWRkaXRpb25hbGx5IGNvbmR1Y3RlZCBzaW1wbGVyIG1vZGVscyBmb3IgZWFjaCBzaWduaWZpY2FudCBmYWN0b3IuIEFzIG1vZGVyYXRvcnMsIHdlIGluY2x1ZGVkIHRoZSBmb2NhbCBmYWN0b3JzLCB0aGUgY29tcGFyZWQgcGFyZW50YWwgc3BlY2llcyDigJMgc3BMTCBvciBzcFNTLCBhbmQgdGhlIGludGVyYWN0aW9uIGJldHdlZW4gdGhlbS4gUmVzcG9uc2UgdmFyaWFibGVzIGFuZCByYW5kb20gZWZmZWN0cyBvZiBzaW1wZXIgbW9kZWxzIHdlcmUgaWRlbnRpY2FsIHRvIGZ1bGwgbW9kZWxzLiANCg0KYGBge3IsIGZpZy5oZWlnaHQgPSAzLjUsIGZpZy53aWR0aCA9IDMuM30NCg0KIyArKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrIw0KIyBUbyBzZXQgcmF3IG1ldGFkYXRhIGluIFggYXhpcywgcmVsb2FkIHJhdyBtZXRhZGF0YSBhbmQgY29tYmluZSB0byB0cmFuc2dyZXNzaW9uIGRhdGFzZXQNCiMgKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyMNCnJhd2RhdCA8LSBkYXQuZnVsbCAlPiUNCiAgc2VsZWN0KC1QaGVuby5kaXZlcmdlbmNlLCAtR2VuZXQuZGl2ZXJnZW5jZSkgJT4lDQogICMgbG5SUiBiZXR3ZWVuIHBhcmVudGFsIHNwZWNpZXMgYXMgcGhlbm90eXBpYyBkaXN0YW5jZQ0KICBtdXRhdGUoUGhlbm8uZGl2ZXJnZW5jZSA9IGFicyhsb2coTW4uc3BML01uLnNwUykpKSAlPiUNCiAgbGVmdF9qb2luKA0KICAgIC4sDQogICAgcmVhZC54bHN4KCIuLi9kYXRhL29yaWdpbmFsLmRhdGEueGxzeCIsIHNoZWV0ID0gIlNwZWNpZXMubGV2ZWwubW9kZXJhdG9ycyIpICU+JQ0KICAgICAgc2VsZWN0KENyb3NzLklELCBHZW5ldC5kaXZlcmdlbmNlKQ0KICAgICkgJT4lDQogICMgTmF0dXJhbCBsb2cgb2YgZ2VuZXRpYyBkaXN0YW5jZQ0KICBtdXRhdGVfYXQoIkdlbmV0LmRpdmVyZ2VuY2UiLCBsb2cpDQoNCiMgIyArKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrIw0KIyAjIFJlZ3Jlc3Npb246IEdlbmV0aWMgZGlzdGFuY2UNCiMgIyArKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrIw0KIyANCiMgIyMgU2V0dGluZyBwcmlvciB0byBsb2dpc3RpYyByZWdyZXNzaW9uICMjIw0KIyBwcmlvciA8LSBsaXN0KA0KIyAgIEI9bGlzdCgNCiMgICAgIG11ID0gcmVwKDAsIDMpLCAjIE4gb2YgY29lZmZpY2llbnQuIChsZXZlbCAtMSkgZm9yIGNhdGVnb3JpY2FsIGZhY3RvcnMsIDEgZm9yIGNvbnRpbnVvdXMgZmFjdG9ycywgMSBmb3IgaW50ZXJjZXB0DQojICAgICBWID0gZ2VsbWFuLnByaW9yKH4gZGlyZWN0aW9uOkdlbmV0LmRpdmVyZ2VuY2UgKyBHZW5ldC5kaXZlcmdlbmNlLA0KIyAgICAgZGF0YSA9IHJhd2RhdCwgIyBmb3JtdWxhIGFuZCBkYXRhDQojICAgICBzY2FsZT1zcXJ0KHBpXjIvMysxKSkpLCAjIGVycm9yIGRpc3RyaWJ1dGlvbiBvZiBsb2dpc3RpYyByZWdyZXNzaW9uDQojICAgUj1saXN0KFY9MSxmaXg9MSksDQojICAgRyA9IGxpc3QoDQojICAgICBHMSA9IGxpc3QoViA9IDEsIG51ID0gMSwgYWxwaGEubXUgPSAwLCBhbHBoYS5WID0gMTAwMCksDQojICAgICBHMiA9IGxpc3QoViA9IDEsIG51ID0gMSwgYWxwaGEubXUgPSAwLCBhbHBoYS5WID0gMTAwMCksDQojICAgICBHMyA9IGxpc3QoViA9IDEsIG51ID0gMSwgYWxwaGEubXUgPSAwLCBhbHBoYS5WID0gMTAwMCksDQojICAgICBHNCA9IGxpc3QoViA9IDEsIG51ID0gMSwgYWxwaGEubXUgPSAwLCBhbHBoYS5WID0gMTAwMCkNCiMgICAgICkNCiMgICApDQojICMjIFBoeWxvZ2VuZXRpYyBiaW5vbWlhbCByZWdyZXNzaW9uICMjIw0KIyBwaHlsbWl4IDwtTUNNQ2dsbW0oDQojICAgZml4ZWQgPSBOb3ZlbHR5IH4gZGlyZWN0aW9uOkdlbmV0LmRpdmVyZ2VuY2UgKyBHZW5ldC5kaXZlcmdlbmNlLA0KIyAgICMgaWRoKFNFKTp1bml0cyB8IHdlaWdodCBieSBTRSBvZiBlZmZlY3Qgc2l6ZQ0KIyAgIHJhbmRvbSA9IH4gU3R1ZHkuSUQgKyBDcm9zcy5JRCArIHNwTC5uYW1lICsgaWRoKFNFKTp1bml0cywNCiMgICBmYW1pbHkgPSAiY2F0ZWdvcmljYWwiLA0KIyAgIHZlcmJvc2UgPSBGQUxTRSwNCiMgICBnaW52ZXJzZSA9IGxpc3Qoc3BMLm5hbWUgPSBwaHlsb19NQ01DKSwNCiMgICBwcmlvciA9IHByaW9yLA0KIyAgIGRhdGEgPSByYXdkYXQsDQojICAgbml0dCA9IDYwMDAwLCAgIyBJbmNyZWFzZSB0aGUgbnVtYmVyIG9mIGl0ZXJhdGlvbnMsIGRlZmF1bHQgaXMgMTMwMDANCiMgICBidXJuaW4gPSA1MDAwICAjIEluY3JlYXNlIHRoZSBudW1iZXIgb2YgYnVybmluLCBkZWZhdWx0IGlzIDMwMDANCiMgKQ0KIyBwaHlsbWl4JFNvbCA8LSBwaHlsbWl4JFNvbC9zcXJ0KDErYzIpDQojICMjIFNhdmUgbW9kZWwgIyMjDQojIHNhdmVSRFMocGh5bG1peCwgZmlsZSA9Ii4uL0FuYWx5c2lzL1ZhcmlhdGlvbi5ub3ZlbHR5LkdlbmV0LmRpdmVyZ2VuY2Uub2JqIikNCiMgDQojICMgKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyMNCiMgIyBSZWdyZXNzaW9uOiBQaGVub3R5cGljIGRpdmVyZ2VuY2UNCiMgIyArKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrIw0KIyANCiMgIyMgU2V0dGluZyBwcmlvciB0byBsb2dpc3RpYyByZWdyZXNzaW9uICMjIw0KIyBwcmlvciA8LSBsaXN0KA0KIyAgIEI9bGlzdCgNCiMgICAgIG11ID0gcmVwKDAsIDMpLCAjIE4gb2YgY29lZmZpY2llbnQuIChsZXZlbCAtMSkgZm9yIGNhdGVnb3JpY2FsIGZhY3RvcnMsIDEgZm9yIGNvbnRpbnVvdXMgZmFjdG9ycywgMSBmb3IgaW50ZXJjZXB0DQojICAgICBWID0gZ2VsbWFuLnByaW9yKH4gZGlyZWN0aW9uOlBoZW5vLmRpdmVyZ2VuY2UgKyBQaGVuby5kaXZlcmdlbmNlLA0KIyAgICAgZGF0YSA9IHJhd2RhdCwgIyBmb3JtdWxhIGFuZCBkYXRhDQojICAgICBzY2FsZT1zcXJ0KHBpXjIvMysxKSkpLCAjIGVycm9yIGRpc3RyaWJ1dGlvbiBvZiBsb2dpc3RpYyByZWdyZXNzaW9uDQojICAgUj1saXN0KFY9MSxmaXg9MSksDQojICAgRyA9IGxpc3QoDQojICAgICBHMSA9IGxpc3QoViA9IDEsIG51ID0gMSwgYWxwaGEubXUgPSAwLCBhbHBoYS5WID0gMTAwMCksDQojICAgICBHMiA9IGxpc3QoViA9IDEsIG51ID0gMSwgYWxwaGEubXUgPSAwLCBhbHBoYS5WID0gMTAwMCksDQojICAgICBHMyA9IGxpc3QoViA9IDEsIG51ID0gMSwgYWxwaGEubXUgPSAwLCBhbHBoYS5WID0gMTAwMCksDQojICAgICBHNCA9IGxpc3QoViA9IDEsIG51ID0gMSwgYWxwaGEubXUgPSAwLCBhbHBoYS5WID0gMTAwMCkNCiMgICAgICkNCiMgICApDQojICMjIFBoeWxvZ2VuZXRpYyBiaW5vbWlhbCByZWdyZXNzaW9uICMjIw0KIyBwaHlsbWl4IDwtTUNNQ2dsbW0oDQojICAgZml4ZWQgPSBOb3ZlbHR5IH4gZGlyZWN0aW9uOlBoZW5vLmRpdmVyZ2VuY2UgKyBQaGVuby5kaXZlcmdlbmNlLA0KIyAgICMgaWRoKFNFKTp1bml0cyB8IHdlaWdodCBieSBTRSBvZiBlZmZlY3Qgc2l6ZQ0KIyAgIHJhbmRvbSA9IH4gU3R1ZHkuSUQgKyBDcm9zcy5JRCArIHNwTC5uYW1lICsgaWRoKFNFKTp1bml0cywNCiMgICBmYW1pbHkgPSAiY2F0ZWdvcmljYWwiLA0KIyAgIHZlcmJvc2UgPSBGQUxTRSwNCiMgICBnaW52ZXJzZSA9IGxpc3Qoc3BMLm5hbWUgPSBwaHlsb19NQ01DKSwNCiMgICBwcmlvciA9IHByaW9yLA0KIyAgIGRhdGEgPSByYXdkYXQsDQojICAgbml0dCA9IDYwMDAwLCAgIyBJbmNyZWFzZSB0aGUgbnVtYmVyIG9mIGl0ZXJhdGlvbnMsIGRlZmF1bHQgaXMgMTMwMDANCiMgICBidXJuaW4gPSA1MDAwICAjIEluY3JlYXNlIHRoZSBudW1iZXIgb2YgYnVybmluLCBkZWZhdWx0IGlzIDMwMDANCiMgKQ0KIyBwaHlsbWl4JFNvbCA8LSBwaHlsbWl4JFNvbC9zcXJ0KDErYzIpDQojICMjIFNhdmUgbW9kZWwgIyMjDQojIHNhdmVSRFMocGh5bG1peCwgZmlsZSA9Ii4uL0FuYWx5c2lzL1ZhcmlhdGlvbi5ub3ZlbHR5LlBoZW5vLmRpdmVyZ2VuY2Uub2JqIikNCg0KIysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrIw0KIyBQbG90DQojKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysjDQoNCmZvciAoaSBpbiBjKCJHZW5ldC5kaXZlcmdlbmNlIiwgIlBoZW5vLmRpdmVyZ2VuY2UiKSkgew0KICANCiAgIyMgTG9hZCBtb2RlbCAjIyMNCiAgcGh5bG1peCA8LSByZWFkUkRTKA0KICAgIHBhc3RlKCIuLi9BbmFseXNpcy9WYXJpYXRpb24ubm92ZWx0eSIsaSwgIm9iaiIsIHNlcCA9ICIuIikNCiAgICApDQogIHJlZyA8LSBzdW1tYXJ5KHBoeWxtaXgkU29sKSRzdGF0aXN0aWNzICU+JQ0KICAgICAgYXMuZGF0YS5mcmFtZSgpDQogIA0KICAjIyBQbG90ICMjIw0KICBwbG90IDwtIGdncGxvdChyYXdkYXQsIGFlcyh4ID0gcmF3ZGF0WyxpXSwgeSA9IHJhd2RhdFssICJOb3ZlbHR5Il0pKSArDQogICAgZ2VvbV9qaXR0ZXIoDQogICAgICBoZWlnaHQgPSAwLjEsIHdpZHRoID0gMCwgYWVzKGNvbG9yID0gZGlyZWN0aW9uKSwgYWxwaGEgPSAwLjMsIHNpemUgPSAwLjINCiAgICAgICkgKw0KICAgICMgTGFyZ2VyIHZhcmlhYmlsaXR5DQogICAgc3RhdF9mdW5jdGlvbigNCiAgICAgIGFlcyhjb2xvciA9ICIrIiksIHNpemUgPSAwLjgsDQogICAgICBmdW4gPSBmdW5jdGlvbih4KSANCiAgICAgICAgMS8oMSArIGV4cCgtKHJlZ1sxLDFdICsgeCoocmVnWzIsMV0rcmVnWzMsMV0pKSkpDQogICAgICApICsNCiAgICAjIFNtYWxsZXIgdmFyaWFiaWxpdHkNCiAgICBzdGF0X2Z1bmN0aW9uKA0KICAgICAgYWVzKGNvbG9yID0gIi0iKSwgc2l6ZSA9IDAuOCwNCiAgICAgIGZ1biA9IGZ1bmN0aW9uKHgpIA0KICAgICAgICAxLygxICsgZXhwKC0ocmVnWzEsMV0gKyB4KnJlZ1syLDFdKSkpDQogICAgICApICsNCiAgICB5bGFiKCJOb3ZlbCBwaGVub3R5cGljIHZhcmlhYmlsaXRpZXMiKSArIA0KICAgIHhsYWIocGFzdGUoaSwgIihsb2cpIikpICsNCiAgICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDIiKSArDQogICAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcz1zZXEoMCwxKSkgKw0KICAgIHJlZ3Jlc3Npb250aGVtZSANCiAgDQogIHByaW50KHBsb3QpDQogICMgZ2dzYXZlKA0KICAjICAgcGxvdCA9IHBsb3QsIA0KICAjICAgZmlsZSA9IHBhc3RlKCIuLi9BbmFseXNpcy9WYXJpYXRpb24uVFMuY29udGludW91cyIsIGksICJzdmciLCBzZXAgPSAiLiIpLCANCiAgIyAgIGhlaWdodCA9IDEuNiwgd2lkdGggPSAxLjcNCiAgIyAgICkNCg0KfQ0KDQpgYGANCg0KYGBge3IsIHJlc3VsdHM9J2FzaXMnLCBmaWcuaGVpZ2h0ID0gMywgZmlnLndpZHRoID0gNn0NCg0KZm9yIChpIGluIGMoIlJlY2lwcm9jYWwiLCAidHJhaXQudHlwZSIpKSB7DQoNCiAgIyBNYWtlIG5ldyBjYXRlZ29yaWNhbCBkYXRhIGNvbWJpbmluZyBkaXJlY3Rpb24gb2YgVFMgYW5kIHRhcmdldCBjYXRlZ29yaWNhbCBmYWN0b3INCiAgZGF0ICU8PiUNCiAgICBtdXRhdGUoaW50ZXJhY3Rpb24gPSBzdHJfYyhkaXJlY3Rpb24sIC5bLCBpXSwgc2VwID0gIl8iKSkNCg0KICAjICMjIFNldHRpbmcgcHJpb3IgdG8gbG9naXN0aWMgcmVncmVzc2lvbiAjIyMNCiAgIyBwcmlvciA8LSBsaXN0KA0KICAjICAgQj1saXN0KA0KICAjICAgICBtdSA9IHJlcCgwLCA0KSwgIyBOIG9mIGNvZWZmaWNpZW50LiAobGV2ZWwgLTEpIGZvciBjYXRlZ29yaWNhbCBmYWN0b3JzLCAxIGZvciBjb250aW51b3VzIGZhY3RvcnMsIDEgZm9yIGludGVyY2VwdA0KICAjICAgICBWID0gZ2VsbWFuLnByaW9yKH4gaW50ZXJhY3Rpb24sDQogICMgICAgIGRhdGEgPSBkYXQsICMgZm9ybXVsYSBhbmQgZGF0YQ0KICAjICAgICBzY2FsZT1zcXJ0KHBpXjIvMysxKSkpLCAjIGVycm9yIGRpc3RyaWJ1dGlvbiBvZiBsb2dpc3RpYyByZWdyZXNzaW9uDQogICMgICBSPWxpc3QoVj0xLGZpeD0xKSwNCiAgIyAgICMgUmVwbGljYXRpbmcgc2FtZSBHIGZvciB0aGUgbnVtYmVyIG9mIHJhbmRvbSBlZmZlY3RzIChoZXJlLCA0KQ0KICAjICAgRyA9IGxpc3QoDQogICMgICAgIEcxID0gbGlzdChWID0gMSwgbnUgPSAxLCBhbHBoYS5tdSA9IDAsIGFscGhhLlYgPSAxMDAwKSwNCiAgIyAgICAgRzIgPSBsaXN0KFYgPSAxLCBudSA9IDEsIGFscGhhLm11ID0gMCwgYWxwaGEuViA9IDEwMDApLA0KICAjICAgICBHMyA9IGxpc3QoViA9IDEsIG51ID0gMSwgYWxwaGEubXUgPSAwLCBhbHBoYS5WID0gMTAwMCksDQogICMgICAgIEc0ID0gbGlzdChWID0gMSwgbnUgPSAxLCBhbHBoYS5tdSA9IDAsIGFscGhhLlYgPSAxMDAwKQ0KICAjICAgICApDQogICMgICApDQogICMgIyMgUnVuIG1vZGVsICMjIw0KICAjIHBoeWxtaXggPC1NQ01DZ2xtbSgNCiAgIyAgIGZpeGVkID0gTm92ZWx0eSB+ICBpbnRlcmFjdGlvbiAtMSwgIyArIHRyYWl0LmRpcmVjdGlvbg0KICAjICAgZmFtaWx5ID0gImNhdGVnb3JpY2FsIiwNCiAgIyAgICMgaWRoKFNFKTp1bml0cyB8IHdlaWdodCBieSBTRSBvZiBlZmZlY3Qgc2l6ZQ0KICAjICAgcmFuZG9tID0gfiBTdHVkeS5JRCArIENyb3NzLklEICsgc3BMLm5hbWUgKyBpZGgoU0UpOnVuaXRzLA0KICAjICAgdmVyYm9zZSA9IEZBTFNFLA0KICAjICAgZ2ludmVyc2UgPSBsaXN0KHNwTC5uYW1lID0gcGh5bG9fTUNNQyksDQogICMgICBwcmlvciA9IHByaW9yLA0KICAjICAgZGF0YSA9IGRhdA0KICAjICkNCiAgIyAjIENvcnJlY3RpbmcgZXN0aW1hdGUNCiAgIyBwaHlsbWl4JFNvbCA8LSBwaHlsbWl4JFNvbC9zcXJ0KDErYzIpDQogICMgIyMgU2F2ZSBtb2RlbCAjIyMNCiAgIyBzYXZlUkRTKA0KICAjICAgcGh5bG1peCwNCiAgIyAgIGZpbGUgPQ0KICAjICAgICBwYXN0ZSgiLi4vQW5hbHlzaXMvVmFyaWF0aW9uLm5vdmVsdHkiLCBpLCAiYWxsdGF4b24ub2JqIiwgc2VwID0gIi4iKQ0KICAjICAgICApDQogIA0KICAjKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysjICANCiAgIyBHcm91cGluZyBpbnRlcmFjdGlvbiB0ZXJtcw0KICAjKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysjDQogIHBoeWxtaXggPC0gcmVhZFJEUygNCiAgICBwYXN0ZSgiLi4vQW5hbHlzaXMvVmFyaWF0aW9uLm5vdmVsdHkiLCBpLCAiYWxsdGF4b24ub2JqIiwgc2VwID0gIi4iKQ0KICAgICkNCiAgDQogIHN1bSA8LSBzdW1tYXJ5KHBoeWxtaXgpJHNvbHV0aW9ucyAlPiUNCiAgICBhcy5kYXRhLmZyYW1lKCkgJT4lDQogICAgcm93bmFtZXNfdG9fY29sdW1uKHZhciA9ICJmYWN0b3JzIikgJT4lDQogICAgbXV0YXRlKA0KICAgICAgIyBJbXBhY3Qgb24gZXhjZWVkaW5nIHVwcGVyIG9yIGxvd2VyIHJhbmdlDQogICAgICBkaXJlY3Rpb24gPQ0KICAgICAgICBpZmVsc2Uoc3RyX2RldGVjdChmYWN0b3JzLCAiaW50ZXJhY3Rpb25cXCsiKSwgDQogICAgICAgICAgICAgICAiRXhjZWVkIHVwcGVyIHJhbmdlIiwNCiAgICAgICAgICAgICAgICJFeGNlZWQgbG93ZXIgcmFuZ2UiDQogICAgICAgICAgICAgICApICU+JQ0KICAgICAgICBhcy5mYWN0b3INCiAgICAgICkgJT4lDQogICAgd2l0aGluKGRpcmVjdGlvbiA8LSBvcmRlcmVkKGRpcmVjdGlvbiwgYygiRXhjZWVkIHVwcGVyIHJhbmdlIiwgIkV4Y2VlZCBsb3dlciByYW5nZSIpKSkgJT4lDQogICAgIyMgQ2hhbmdlIGZhY3RvciBuYW1lcyAjIyMNCiAgICB3aXRoaW4oDQogICAgICBmYWN0b3JzIDwtIHN0cl9yZW1vdmVfYWxsKGZhY3RvcnMsICJpbnRlcmFjdGlvbi5fIikNCiAgICAgICkgICAgICAgDQogIA0KICAgICMrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyMgIA0KICAgICMgUGxvdA0KICAgICMrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyMNCiAgICBjYXRlZ29yaWNhbHBsb3QgPC0gZ2dwbG90KHN1bSwgYWVzKHggPSBwb3N0Lm1lYW4sIHkgPSBmYWN0b3JzKSkgKw0KICAgICAgIyBWZXJ0aWNhbCBsaW5lDQogICAgICBnZW9tX3ZsaW5lKA0KICAgICAgICB4aW50ZXJjZXB0ID0gMCwgc2l6ZSA9IDAuMywNCiAgICAgICAgY29sb3VyID0gImdyZXkzMCIsIGxpbmV0eXBlID0gImRvdHRlZCINCiAgICAgICAgKSArDQogICAgICAjIENJDQogICAgICBnZW9tX2Vycm9yYmFyaCgNCiAgICAgICAgYWVzKHhtaW4gPSBzdW1bLCAnbC05NSUgQ0knXSwgeG1heCA9IHN1bVssICd1LTk1JSBDSSddKSwNCiAgICAgICAgaGVpZ2h0ID0gLjAwMDENCiAgICAgICAgKSArDQogICAgICBnZW9tX3BvaW50KHNpemUgPSAxLjMsIHNoYXBlID0gMTcpICsNCiAgICAgICMgVGl0bGUNCiAgICAgIHlsYWIoIiIpICsgeGxhYigiRWZmZWN0IG9uIG5vdmVsdHkgaW4gcGhlbm90eXBpYyBtZWFucyIpICsNCiAgICAgIGdndGl0bGUoaSkgKw0KICAgICAgIyBDb21iaW5lIGRpZmZlcmVudCBwbG90cyBmb3IgbWFpbiBmYWN0b3JzIGFuZCBpbnRlcmFjdGlvbnMNCiAgICAgIGZhY2V0X2dyaWQoDQogICAgICAgIGRpcmVjdGlvbiB+Liwgc2NhbGVzID0gImZyZWUiLCBkcm9wID0gVFJVRSwNCiAgICAgICAgbGFiZWxsZXIgPSBsYWJlbF93cmFwX2dlbih3aWR0aCA9IDExKQ0KICAgICAgICApICsNCiAgICAgIGZvcmVzdHRoZW1lDQogICAgcHJpbnQoY2F0ZWdvcmljYWxwbG90KQ0KICANCiAgIyBnZ3NhdmUoDQogICMgICAgIHBsb3QgPSBjYXRlZ29yaWNhbHBsb3QgKyB0aGVtZShheGlzLnRleHQueSA9IGVsZW1lbnRfYmxhbmsoKSksDQogICMgICAgIGZpbGUgPSANCiAgIyAgICAgICBwYXN0ZSgiLi4vQW5hbHlzaXMvVmFyaWF0aW9uLm5vdmVsdHkuY2F0ZWdvcmljYWwiLCBpLHRheG9uLCAic3ZnIiwgc2VwID0gIi4iKSwNCiAgIyAgICAgaGVpZ2h0ID0gMS44LCB3aWR0aCA9IDIuNQ0KICAjICAgICApDQogIA0KfQ0KDQoNCmBgYA0KDQo8ZGl2IHN0eWxlPSJtYXJnaW4tYm90dG9tOjE4MHB4OyI+DQo8L2Rpdj4NCg0KIyBQaGVub3R5cGljIHZhcmlhYmlsaXR5IG9mIG5vdmVsIHBoZW5vdHlwZQ0KDQojIyBEYXRhc2V0IHN1bW1hcnkNCg0KUmVsYXRpdmUgdmFyaWFiaWxpdHkgaW5kaWNhdGVzIEYxIGh5YnJpZHMnIHBoZW5vdHlwaWMgdmFyaWFiaWxpdHkgc2l6ZSAoQ1YpIGNvbXBhcmVkIHRvIHRob3NlIG9mIHBhcmVudHMuIDxicj4NCg0KKiBTbWFsbGVyOiBzbWFsbGVyIHZhcmlhYmlsaXR5IHRoYW4gb2YgYm90aCBwYXJlbnRzDQoNCiogSW50ZXJtZWRpYXRlOiBpbnRlcm1lZGlhdGUgYmV0d2VlbiBwYXJlbnRzJyB2YXJpYWJpbGl0eSANCg0KKiBMYXJnZXI6IGxhcmdlciB2YXJpYWJpbGl0eSB0aGFuIG9mIGJvdGggcGFyZW50cw0KDQpgYGB7ciwgcmVzdWx0cz0nYXNpcyd9DQoNCmRhdCA8LSByZWFkLmNzdigiLi4vZGF0YS9kYXQubm92ZWx0eS5jc3YiLCBoZWFkID0gVFJVRSkgJT4lIA0KICBtdXRhdGVfYXQodmFycygibWVhbi5ub3ZlbHR5IiwgInJlbGF0aXZlLnZhciIpLCBhcy5mYWN0b3IpICU+JSANCiAgd2l0aGluKA0KICAgIHJlbGF0aXZlLnZhciA8LQ0KICAgICAgb3JkZXJlZChyZWxhdGl2ZS52YXIsIGxldmVscyA9IGMoIlNtYWxsZXIiLCAiSW50ZXJtZWRpYXRlIiwgIkxhcmdlciIpKSwNCiAgICBtZWFuLm5vdmVsdHkgPC0gDQogICAgICBvcmRlcmVkKG1lYW4ubm92ZWx0eSwgbGV2ZWxzID0gYygiTm9ubm92ZWwiLCAiTm92ZWwiKSkNCiAgKQ0KDQpkYXQucmVsYXQudmFyIDwtIGRhdCAlPiUgDQogIGdyb3VwX2J5KG1lYW4ubm92ZWx0eSwgcmVsYXRpdmUudmFyKSAlPiUgDQogIHN1bW1hcmlzZSgnTiAoVHJhaXQgb2JzZXJ2YXRpb24pJyA9IGxlbmd0aChFUy5JRCkpICU+JSANCiAgc3ByZWFkKGtleSA9IG1lYW4ubm92ZWx0eSwgdmFsdWUgPSAnTiAoVHJhaXQgb2JzZXJ2YXRpb24pJykgJT4lDQogIGFzLmRhdGEuZnJhbWUoKSAlPiUNCiAgbXV0YXRlKA0KICAgICJOb25ub3ZlbCBwaGVub3R5cGUgKCUgdHJhaXQgb2JzKSIgPSANCiAgICAgIE5vbm5vdmVsL3N1bShOb25ub3ZlbCkqMTAwLCANCiAgICAiTm92ZWwgcGhlbm90eXBlICglIHRyYWl0IG9icykiID0gDQogICAgICBOb3ZlbC9zdW0oTm92ZWwpKjEwMCwNCiAgICBUcmFpdC5jb3VudCA9IE5vbm5vdmVsICsgTm92ZWwgIyBOIG9mIHRyYWl0cyBhdCBlYWNoIHZhcmlhYmlsaXR5IGxldmVscw0KICApICU+JQ0KICByZW5hbWUoJ1JlbGF0aXZlLnZhcmlhYmlsaXR5JyA9ICdyZWxhdGl2ZS52YXInKQ0KDQpnZ3Bsb3QoDQogIGRhdC5yZWxhdC52YXIgJT4lDQogICAgZHBseXI6OnNlbGVjdCgtY29udGFpbnMoInRyYWl0IG9icyIpLCAtVHJhaXQuY291bnQpICU+JQ0KICAgIHBpdm90X2xvbmdlcigNCiAgICAgIGNvbCA9IC1SZWxhdGl2ZS52YXJpYWJpbGl0eSwNCiAgICAgIG5hbWVzX3RvID0gIlBoZW5vdHlwaWMubm92ZWx0eSIsDQogICAgICB2YWx1ZXNfdG8gPSAiQ291bnQiDQogICAgICApICU+JQ0KICAgIGxlZnRfam9pbihkYXQucmVsYXQudmFyKSAlPiUNCiAgICBhcy5kYXRhLmZyYW1lICU+JQ0KICAgIG11dGF0ZV9hdCgiUGhlbm90eXBpYy5ub3ZlbHR5IiwgYXMuZmFjdG9yKSwNCiAgYWVzKA0KICAgIHkgPSBDb3VudCwgDQogICAgeCA9IFRyYWl0LmNvdW50LzIsICAjIGVuc3VyZSBlYWNoIHBpZSBjaGFydCBpcyAibGVmdC1hbGlnbmVkIg0KICAgIHdpZHRoID0gVHJhaXQuY291bnQsICMgc2FtcGxlIHNpemUgKE4gb2YgdHJhaXRzIGF0IGVhY2ggdmFyaWFiaWxpdHkgbGV2ZWxzKQ0KICAgIGZpbGwgPSBQaGVub3R5cGljLm5vdmVsdHkNCiAgICApDQogICkgKw0KICBnZW9tX2Jhcihwb3NpdGlvbj0iZmlsbCIsIHN0YXQgPSAiaWRlbnRpdHkiKSArDQogIGZhY2V0X2dyaWQofiBSZWxhdGl2ZS52YXJpYWJpbGl0eSkgKw0KICAjIFBpZSBjaGFydA0KICBjb29yZF9wb2xhcigieSIpICsNCiAgZ2d0aXRsZSgiTm92ZWwgYW5kIG5vbi1ub3ZlbCBwaGVub3R5cGVzIG9jY3VwYW5jaWVzIGF0DQogICAgICAgICAgZWFjaCByZWxhdGl2ZSB2YXJpYWJpbGl0eSBsZXZlbHMiKSArDQogIHhsYWIoIlRyYWl0IGNvdW50cyIpICsgeWxhYigiUmVsYXRpdmUgdmFyaWFiaWxpdHkgbGV2ZWxzIikgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSkNCg0KDQpkYXQucmVsYXQudmFyICU+JQ0KICByZW5hbWUoDQogICdOb25ub3ZlbC5waGVub3R5cGUgKE4pJyA9ICdOb25ub3ZlbCcsDQogICdOb3ZlbC5waGVub3R5cGUgKE4pJyA9ICdOb3ZlbCcNCiAgKSAlPiUNCiAga2FibGUoImh0bWwiLCBkaWdpdHMgPSAxLCBjYXB0aW9uID0gIkRhdGFzZXQgc3VtbWFyeSIpICU+JQ0KICBrYWJsZV9zdHlsaW5nKCJzdHJpcGVkIiwgcG9zaXRpb24gPSAibGVmdCIpDQoNCmBgYA0KDQo8ZGl2IHN0eWxlPSJtYXJnaW4tYm90dG9tOjcwcHg7Ij4NCjwvZGl2Pg0KDQpgYGB7ciwgZmlnLmhlaWdodCA9IDYuNSwgZmlnLmNhcCA9ICJGaWd1cmUgUzMuIFBoeWxvZ2VuZXRpYyB0cmVlIHVzZWQsIHdoaWNoIHdhcyBiYXNlZCBvbiB0cmVlIG9mIHRoZSBwYXJlbnRhbCBzcGVjaWVzIHdpdGhpbiBhIGNyb3NzIHdoaWNoIG5hbWUgY29tZXMgZWFybGllciBpbiBhbHBoYWJldGljYWwgb3JkZXIifQ0KDQojKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrIw0KIyBSZWFkIGNyZWF0ZSB0cmVlIGJhc2VkIG9uIE9wZW4gVHJlZSBvZiBMaWZlIHRheG9ub215DQojKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrIw0KDQojICMgbWF0Y2hpbmcgbmFtZXMgZnJvbSBvcGVuIHRyZWUgdGF4b25vbXkNCiMgdGF4YSA8LSB0bnJzX21hdGNoX25hbWVzKA0KIyAgIG5hbWVzID0gbGV2ZWxzKGRhdCRzcDEubmFtZSkgJT4lDQojICAgICBzdHJfcmVwbGFjZV9hbGwoIl8iLCAiICIpLA0KIyAgIGNvbnRleHRfbmFtZSA9ICJBbmltYWxzIg0KIyAgICkNCiMgDQojICMgQ3JlYXRlIHRyZWUNCiMgdHJlZSA8LSB0b2xfaW5kdWNlZF9zdWJ0cmVlKG90dF9pZHMgPSB0YXhhJG90dF9pZCkNCiMgdHJlZSR0aXAubGFiZWwgJTw+JQ0KIyAgIHN0cmlwX290dF9pZHMgIyByZW1vdmUgT1RUIElEcyBmcm9tIHRpcCBsYWJlbHMNCiMgIyByYW5kb21seSBzb2x2ZSBub24tYmluYXJ5IHBoeWxvZ2VueQ0KIyBzZXQuc2VlZCg2KQ0KIyBiaW4udHJlZSA8LSBtdWx0aTJkaSh0cmVlLCByYW5kb20gPSBUKQ0KIyBwcmludCgiUmFuZG9tbHkgc29sdmVkIHBoeWxvZ2VueSIpDQojIA0KIyAjIEluZGljYXRlIG1pc21hdGNoIGJldHdlZW4gdGlwIGxhYmVscyAmIGRhdGFzZXQgc3BlY2llcyBuYW1lcw0KIyBzZXRkaWZmKGxldmVscyhhcy5mYWN0b3IoYmluLnRyZWUkdGlwLmxhYmVsKSksIGxldmVscyhkYXQkc3AxLm5hbWUpKQ0KIyBzZXRkaWZmKGxldmVscyhkYXQkc3AxLm5hbWUpLCBsZXZlbHMoYXMuZmFjdG9yKGJpbi50cmVlJHRpcC5sYWJlbCkpKQ0KIyAjIEZpeCBuYW1lcyBvZiB0aXAgbGFiZWxzDQojIGJpbi50cmVlJHRpcC5sYWJlbCAlPD4lIHN0cl9yZXBsYWNlX2FsbCgiRHJ5b3BoeXRlcyIsICJIeWxhIikNCiMgDQojIHdyaXRlLnRyZWUoYmluLnRyZWUsIGZpbGU9ICIuLi9kYXRhL3BoeWxvLm5vdmVsdHkudHJlIikNCg0KIysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysjDQojIFBoeWxvZ2VuZXRpYyB0cmVlIGZvciBtY21jZ2xtbSANCiMrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrIw0KDQojIGNvbXB1dGUgYnJhbmNoIGxlbmd0aHMgb2YgdHJlZQ0KcGh5bG9fYnJhbmNoIDwtIHJlYWQudHJlZShmaWxlID0gIi4uL2RhdGEvcGh5bG8ubm92ZWx0eS50cmUiKSAlPiUNCiAgY29tcHV0ZS5icmxlbihtZXRob2QgPSAiR3JhZmVuIiwgcG93ZXIgPSAxKQ0KcGxvdC5waHlsbyhwaHlsb19icmFuY2gsIGNleCA9IDAuNykNCg0KIyBzYXZpbmcgcGh5bG9nZW5laWMgbWF0cml4DQpwaHlsb19jb3IgPC0gdmN2KHBoeWxvX2JyYW5jaCwgY29yID0gVCkNCg0KIyBnZW5lcmF0aW5nIGludmVyc2UgcGh5bG9nZW5ldGljIG1hdHJpeCBmb3IgTUNNQ2dsbW0NCnBoeWxvX2JyYW5jaCRub2RlLmxhYmVsIDwtIE5VTEwNCnBoeWxvX01DTUMgPC0gTUNNQ2dsbW06OmludmVyc2VBKHBoeWxvX2JyYW5jaCwgbm9kZXMgPSAiQUxMIiwgc2NhbGUgPSBUUlVFKSRBaW52DQoNCmBgYA0KDQo8ZGl2IHN0eWxlPSJtYXJnaW4tYm90dG9tOjcwcHg7Ij4NCjwvZGl2Pg0KDQoNCiMjIFBoeWxvZ2VuZXRpYyBvcmRpbmFsIChwcm9iaXQpIHJlZ3Jlc3Npb24NCkhlcmUgd2UgYXNrIGlmIHBoZW5vdHlwaWMgbm92ZWx0eSBhc3NvY2lhdGUgd2l0aCByZWxhdGl2ZSB2YXJpYWJpbGl0eSBsZXZlbHMuIFdlIGNvbmR1Y3RlZCBvcmRpbmFsIHJlZ3Jlc3Npb24sIGVtcGxveWluZyBjYXRlZ29yaWNhbCBvcmRlcmVkIHZhcmlhYmlsaXR5IGxldmVscyAoc21hbGxlciA8IGludGVybWVkaWF0ZSA8IGxhcmdlciwgc2VlIGFib3ZlKSBhcyByZXNwb25zZSB2YXJpYWJsZSwgYW5kIGNhdGVnb3JpY2FsIHRyYWl0IG1lYW4gbm92ZWx0eSBsZXZlbHMgKGZpeGVkIGVmZmVjdCBgbWVhbi5ub3ZlbHR5YCB3aXRoIDIgbGV2ZWxzOiBgTm92ZWxgIHZzIGBOb25ub3ZlbGApIGFzIG1vZGVyYXRvciB2YXJpYWJsZSwgdXNpbmcgYE1DTUNnbG1tYCBmdW5jdGlvbi4gDQpUaGUgbW9kZWwgaW5jbHVkZWQgZm9sbG93aW5nIFJhbmRvbSBlZmZlY3RzIGVzdGltYXRlczogDQoNCiogYFN0dWR5LklEYDogUHJpbWFyeSBzdHVkaWVzDQoNCiogYHNwMS5uYW1lYDogUGh5bG9nZW55IG9mIHBhcmVudGFsIHNwZWNpZXMNCg0KKiBgQ3Jvc3MuSURgOiBQYXJlbnRhbCBzdHJhaW4gdXNlZCBpbiB0aGUgY3Jvc3NpbmcuIERpc2NyaW1pbmF0ZSBpbnRyYXNwZWNpZmljIHBvcHVsYXRpb25zDQoNCiogYGNyb3NzYDogQ3Jvc3NpbmcgZGlyZWN0aW9uDQoNCiogYFNFLnVuaXRzYDogU2FtcGxpbmcgdmFyaWFuY2Ugb2YgZWZmZWN0IHNpemUNCg0KYGBge3J9DQoNCiMgcHJpb3IxPC1saXN0KA0KIyAgIEI9bGlzdCgNCiMgICAgIG11PWMoMCwwKSwNCiMgICAgIFY9Z2VsbWFuLnByaW9yKH5tZWFuLm5vdmVsdHksIGRhdGE9c2VsZWN0KGRhdCwgLXRyYWl0KSwgc2NhbGU9c3FydCgxKzEpKQ0KIyAgICAgKSwNCiMgICBSPWxpc3QoVj0xLGZpeD0xKSwNCiMgICBHID0gbGlzdCgNCiMgICAgIEcxID0gbGlzdChWID0gMSwgbnUgPSAxLCBhbHBoYS5tdSA9IDAsIGFscGhhLlYgPSAxMDAwKSwNCiMgICAgIEcyID0gbGlzdChWID0gMSwgbnUgPSAxLCBhbHBoYS5tdSA9IDAsIGFscGhhLlYgPSAxMDAwKSwNCiMgICAgIEczID0gbGlzdChWID0gMSwgbnUgPSAxLCBhbHBoYS5tdSA9IDAsIGFscGhhLlYgPSAxMDAwKSwNCiMgICAgIEczID0gbGlzdChWID0gMSwgbnUgPSAxLCBhbHBoYS5tdSA9IDAsIGFscGhhLlYgPSAxMDAwKSwNCiMgICAgIEc0ID0gbGlzdChWID0gMSwgbnUgPSAxLCBhbHBoYS5tdSA9IDAsIGFscGhhLlYgPSAxMDAwKQ0KIyAgICAgKQ0KIyAgICkNCiMgDQojIHBoeWxtaXggPC1NQ01DZ2xtbSgNCiMgICBmaXhlZCA9IHJlbGF0aXZlLnZhciB+IG1lYW4ubm92ZWx0eSwNCiMgICBmYW1pbHkgPSAib3JkaW5hbCIsDQojICAgcmFuZG9tID0gfiBTdHVkeS5JRCArIENyb3NzLklEICsgc3AxLm5hbWUgKyBjcm9zcyArIEVTLklELA0KIyAgIHZlcmJvc2UgPSBGQUxTRSwNCiMgICBwcmlvciA9IHByaW9yMSwNCiMgICBnaW52ZXJzZSA9IGxpc3Qoc3AxLm5hbWUgPSBwaHlsb19NQ01DKSwNCiMgICBkYXRhID0gc2VsZWN0KGRhdCwgLXRyYWl0KSwNCiMgICBuaXR0ID0gNjAwMDAsICAjIEluY3JlYXNlIHRoZSBudW1iZXIgb2YgaXRlcmF0aW9ucywgZGVmYXVsdCBpcyAxMzAwMA0KIyAgIGJ1cm5pbiA9IDUwMDAgICMgSW5jcmVhc2UgdGhlIG51bWJlciBvZiBidXJuaW4sIGRlZmF1bHQgaXMgMzAwMA0KIyAgICkNCiMgDQojICMjIFNhdmUgbW9kZWwgIyMjDQojIHNhdmVSRFMocGh5bG1peCwgZmlsZSA9ICIuLi9BbmFseXNpcy9ub3ZlbHR5Lm1lYW4udmFyLm9iaiIpDQoNCiMjIExvYWQgbW9kZWwgIyMjDQpwaHlsbWl4IDwtIHJlYWRSRFMoIi4uL0FuYWx5c2lzL25vdmVsdHkubWVhbi52YXIub2JqIikNCg0KIysrKysrKysrKysrKysrKysrKysrKysrKysrKyMNCiMgRml4ZWQgZWZmZWN0cyBvdXRwdXQgDQojKysrKysrKysrKysrKysrKysrKysrKysrKysrIw0KZ2V0X2ZpeGVkLk1DTUNnbG1tKHN1bW1hcnkocGh5bG1peCkkc29sdXRpb25zKSAlPiUNCiAgZHBseXI6OnNlbGVjdCgiRmFjdG9ycyIsICJFc3RpbWF0ZXMiLCAiOTUlIGNyZWRpYmxlIGludGVydmFsIiwgIlAiLCAiRGVzY3JpcHRpb24iKSAlPiUNCiAga2FibGUoImh0bWwiLCBkaWdpdHMgPSAzLCBjYXB0aW9uID0gIkZpeGVkIGVmZmVjdHMgZXN0aW1hdGVzIikgJT4lIA0KICBrYWJsZV9zdHlsaW5nKCJzdHJpcGVkIiwgcG9zaXRpb24gPSAibGVmdCIpDQoNCiMrKysrKysrKysrKysrKysrKysrKysrKysrKysjDQojIFJhbmRvbSBlZmZlY3RzIG91dHB1dCANCiMrKysrKysrKysrKysrKysrKysrKysrKysrKysjDQojIHRyYW5zZm9ybWF0aW9uIGZvciB2YXJhaW5jZQ0KZ2V0X3JhbmRvbS5NQ01DZ2xtbShzdW1tYXJ5KHBoeWxtaXgkVkNWLygxK2MyKSkpICU+JQ0KICBrYWJsZSgiaHRtbCIsIGRpZ2l0cyA9IDIsIGNhcHRpb24gPSAiUmFuZG9tIGVmZmVjdHMgZXN0aW1hdGVzIikgJT4lIA0KICBrYWJsZV9zdHlsaW5nKCJzdHJpcGVkIiwgcG9zaXRpb24gPSAibGVmdCIpDQoNCmBgYA0KDQpUaGUgcGhlbm90eXBpYyBub3ZlbHR5IChgbWVhbi5ub3ZlbHR5Tm92ZWxgKSBpbmZsdWVuY2VkIHBvc2l0aXZlbHkuIFRoaXMgaW5kaWNhdGVzIHRoYXQsIGNvbXBhcmVkIHRvIG5vbi1ub3ZlbCBwaGVub3R5cGVzLCBub3ZlbCBwaGVub3R5cGVzIGhhdmUgZ3JlYXRlciBjaGFuY2VzIHRvIGJlIG1vcmUgdmFyaWFibGUgdGhhbiBwYXJlbnRzJyBwaGVub3R5cGVzLiANCg0KDQo8ZGl2IHN0eWxlPSJtYXJnaW4tYm90dG9tOjE4MHB4OyI+DQo8L2Rpdj4NCg0KIyBUcmFpdCBtb3NhaWNpc20NCg0KRjEgaHlicmlkcyBjYW4gYmUgc2VlbiBhcyDigJxhIG1vc2FpYyBvZiBib3RoIHBhcmVudGFsIGFuZCBpbnRlcm1lZGlhdGUgbW9ycGhvbG9naWNhbCBjaGFyYWN0ZXJzIHJhdGhlciB0aGFuIGp1c3QgaW50ZXJtZWRpYXRlIG9uZXMiIFtSaWVzZWJlcmcgYW5kIEVsbHN0cmFuZCAxOTkzXShodHRwczovL2RvaS5vcmcvMTAuMTA4MC8wNzM1MjY4OTMwOTcwMTkwMikuIFRoYXQgaXMsIEYxIGh5YnJpZCBpbmRpdmlkdWFscyBvZnRlbiBjb25zaXN0IG9mIHRyYXRzIGNsb3NlbHkgcmVzZW1ibGUgb25lIHBhcmVudCwgaW50ZXJtZWRpYXRlLCBhbmQgcmVzZW1ibGUgdGhlIG90aGVyIHBhcmVudC4gTW9zYWljaXNtIGluZGljYXRlcyB0ciBpbnRlZ3JhdGlvbiBvZiBwYXJlbnRzIGFyZSBvZnRlbiBjb2xsYXBzZSBpbiBGMSBoeWJyaWRzLiBIZXJlIHdlIGludmVzdGlnYXRlIHRoZSBzdHJlbmd0aCBvZiB0cmFpdCBtb3NhaWNpc20gaW4gbWFsZSBtYXRpbmcgdHJhaXRzLg0KDQo8ZGl2IHN0eWxlPSJtYXJnaW4tYm90dG9tOjcwcHg7Ij4NCjwvZGl2Pg0KDQojIyBkPHN1Yj5taXNtYXRjaDwvc3ViPiBjYWxjdWxhdGlvbg0KDQpUbyBxdWFudGlmeSB0cmFpdCBtb3NhaWNpc20gaW4gZWFjaCBjcm9zc2luZywgd2UgY2FsY3VsYXRlZCBkPHN1Yj5taXNtYXRjaDwvc3ViPiAgZm9sbG93aW5nIFtUaG9tcHNvbiBldCBhbC5dKGh0dHBzOi8vd3d3LmJpb3J4aXYub3JnL2NvbnRlbnQvMTAuMTEwMS84MTg2NTh2MS5mdWxsI2Rpc3AtZm9ybXVsYS0xKSAtQFRob21wc29uMjAyMS4gZDxzdWI+bWlzbWF0Y2g8L3N1Yj4gd2FzIGNhbGN1bGF0ZWQgYXMgZm9sbG93czoNCg0KJGRfe21pc21hdGNofSA9IFxzcXJ0ezJ9ICogXHNxcnR7IFpfaV4yICsgWl9qXjIgLSBcZnJhY3taX2kgKyBaX2p9e1xzcXJ0ezJ9fV4yIH0kDQo8YnI+DQpXaGVyZSAkWl9pJCwgc3RhbmRhcmRpemVkIGh5YnJpZCB0cmFpdCB2YWx1ZSBpbiB0cmFpdCAkaSQsIGlzIDxicj4NCiRaX2kgPSBcZnJhY3toeWJfaSAtIHNwU1NfaX17c3BMTF9pIC0gc3BTU19pfSQgPGJyPg0KDQokWl9pJCBpcyAwLTEgaWYgRjEgcGhlbm90eXBpYyBtZWFuIGxpZXMgd2l0aGluIHRoZSByYW5nZSBvZiBwYXJlbnRzLiBXZSBub3RlLCBob3dldmVyLCBub3ZlbHR5IGluIHBoZW5vdHlwaWMgbWVhbnMgKHRyYW5zZ3Jlc3NpdmUgc2VncmVnYXRpb24pIGNhbiByZXN1bHQgaW4gcXVpdGUgbGFyZ2UgJFpfaSQ6IHdoZW4gdHJhaXQgc2l6ZSBpcyBsYXJnZSBhbmQgcGFyZW50YWwgcGhlbm90eXBpYyBkaXZlcmdlbmNlIGlzIHNtYWxsLCBub3ZlbCBoeWJyaWQgcGhlbm90eXBlIHdpbGwgcmVzdWx0IGluIHF1aXRlIGxhcmdlICRaX2kkLiBUaGlzIHNlZW1zIG9jY3VycmVkIGluIG1pY2UgKHNlZSBiZWxsb3cpIDxicj4NCg0KYGBge3J9DQoNCmRhdCA8LSBvcmlnaW5hbC5kYXQgJT4lDQogIHNlbGVjdChTdHVkeS5JRCwgQ3Jvc3MuSUQsIHRheGEsIEdlbnVzLCBSZWNpcHJvY2FsLCBjb250YWlucygiTW4iKSkgJT4lDQogICMgR2F0aGVyIHJlY2lwcm9jYWwgaHlicmlkIGRhdGENCiAgZ2F0aGVyKA0KICAgIGtleSA9IEh5YnJpZCwgdmFsdWUgPSBNbi5oeWJyaWQsIA0KICAgIC1jKFN0dWR5LklELCBDcm9zcy5JRCwgdGF4YSwgR2VudXMsIFJlY2lwcm9jYWwpLCAtY29udGFpbnMoIk1uLnNwIikNCiAgICApICU+JQ0KICBkcm9wX25hKE1uLmh5YnJpZCkgJT4lDQogICMgQ2FsY3VsYXRlIHN0YW5kYXJkaXplZCBoeWJyaWQgcGhlbm90eXBlIG1lYW4NCiAgbXV0YXRlKA0KICAgIERvbWluYW5jZSA9IGlmZWxzZSgNCiAgICAgIE1uLnNwMSA+IE1uLnNwMiwgDQogICAgICAoTW4uaHlicmlkIC0gTW4uc3AyKS9hYnMoTW4uc3AxIC0gTW4uc3AyKSwNCiAgICAgIChNbi5oeWJyaWQgLSBNbi5zcDEpL2FicyhNbi5zcDEgLSBNbi5zcDIpDQogICAgKQ0KICApICU+JQ0KICBtdXRhdGVfYXQoIkNyb3NzLklEIiwgYXMuZmFjdG9yKSAlPiUNCiAgYXJyYW5nZSh0YXhhLCBHZW51cywgQ3Jvc3MuSUQsIEh5YnJpZCkgJT4lDQogICMgb25seSBnZXQgY3Jvc3NlcyB3aXRoID4gMiB0cmFpdHMNCiAgIyBSZWNpcHJvY2FsIGh5YnJpZHMgYXJlIHNlcGFyYXRlZA0KICBncm91cF9ieShDcm9zcy5JRCwgSHlicmlkLCB0YXhhLCBHZW51cywgU3R1ZHkuSUQsIFJlY2lwcm9jYWwpICU+JQ0KICBmaWx0ZXIobigpID4gMikgJT4lDQogICMgQ3JlYXRlIGFsbCBjb21iaW5hdGlvbnMgb2Ygc3RhbmRhcmRpemVkIGh5YnJpZCBwaGVub3R5cGUgbWVhbg0KICBkbyhkYXRhLmZyYW1lKHQoY29tYm4oLiREb21pbmFuY2UsIDIpKSkpICU+JQ0KICAjIENhbGN1bGF0ZSBkb21pbmFuY2UgbWlzbWF0Y2gNCiAgbXV0YXRlKA0KICAgIE1pc21hdGNoID0gc3FydCgyKSAqIHNxcnQoIFgxXjIgKyBYMl4yIC0gKCAoWDEgKyBYMikgLyBzcXJ0KDIpICleMiApLA0KICAgIE1pc21hdGNoLmxvZyA9IGxvZyhNaXNtYXRjaCkNCiAgKSAlPiUNCiAgbGVmdF9qb2luKG1ldGEpICU+JQ0KICBtdXRhdGVfaWYoaXMuY2hhcmFjdGVyLCBhcy5mYWN0b3IpICU+JQ0KICB3aXRoaW4odGF4YSA8LSBvcmRlcmVkKHRheGEsIGxldmVscyA9IGMoIk5ldXJvcHRlcmEiLCAiQ29sZW9wdGVyYSIsICJEaXB0ZXJhIiwgIkxlcGlkb3B0ZXJhIiwgIk9ydGhvcHRlcmEiLCAiQXZlcyIsICJSb2RlbnRpYSIsICJBbnVyYSIsICJDaWNobGlmb3JtZXMiKSkpICU+JQ0KICBhcy5kYXRhLmZyYW1lDQoNCmBgYA0KPGRpdiBzdHlsZT0ibWFyZ2luLWJvdHRvbTo3MHB4OyI+DQo8L2Rpdj4NCg0KIyMgRGlzdHJpYnV0aW9uIG9mIGQ8c3ViPm1pc21hdGNoPC9zdWI+IA0KDQpgYGB7cn0NCg0KZGF0ICU+JSANCiAgc3VtbWFyaXNlKA0KICAgICdUcmFpdCBjb21iaW5hdGlvbicgPSBsZW5ndGgoWDEpLA0KICAgICdTcGVjaWVzIHBhaXInID0gbGVuZ3RoKHVuaXF1ZShzcGVjaWVzLnBhaXIpKSwNCiAgICAnQ3Jvc3NpbmcnID0gbGVuZ3RoKHVuaXF1ZShDcm9zcy5JRCkpDQogICAgKSAlPiUgDQogIGthYmxlKCJodG1sIiwgY2FwdGlvbiA9ICJEYXRhc2V0IHN1bW1hcnkiKSAlPiUgDQogIGthYmxlX3N0eWxpbmcoInN0cmlwZWQiLCBwb3NpdGlvbiA9ICJsZWZ0IikNCg0KZ2dwbG90KGRhdGEgPSBkYXQsIGFlcyh4ID0gQ3Jvc3MuSUQsIHkgPSBNaXNtYXRjaCkpICsNCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNCwgYWVzKGNvbG9yID0gSHlicmlkKSkgKw0KICB4bGFiKCJDcm9zcyBJRCIpICsgeWxhYigiZG1pc21hdGNoIikgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSArDQogIGZhY2V0X2dyaWQofnRheGEsIHNjYWxlcyA9ICJmcmVlIikgKw0KICBnZ3RpdGxlKCJBbGwgZG1pc21hdGNoIHZhbHVlcyBhY3Jvc3Mgb3JkZXJzIikNCg0KZ2dwbG90KA0KICBkYXRhID0gZGF0ICU+JQ0KICAgIGZpbHRlcighZ3JlcGwoIm11c2N1bHVzIiwgQ3Jvc3MuSUQpKSwgDQogIGFlcyh4ID0gQ3Jvc3MuSUQsIHkgPSBNaXNtYXRjaCkpICsNCiAgeGxhYigiQ3Jvc3MgSUQiKSArIHlsYWIoImRtaXNtYXRjaCIpICsNCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNCwgYWVzKGNvbG9yID0gSHlicmlkKSkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSArDQogIGZhY2V0X2dyaWQofnRheGEsIHNjYWxlcyA9ICJmcmVlIikgKw0KICBnZ3RpdGxlKCJkbWlzbWF0Y2ggYWNyb3NzIG9yZGVycyBleGNsdWRpbmcgUm9kZW50aWEiKQ0KDQpgYGANCmQ8c3ViPm1pc21hdGNoPC9zdWI+IGlzIHF1aXRlIGxhcmdlIGluIGNyb3NzaW5nIGludm9sdmluZyBtaWNlcyAoUm9kZW50aWEpLCBkdWUgdG8gbGFyZ2UgdHJhaXQgdmFsdWUuDQoNCjxkaXYgc3R5bGU9Im1hcmdpbi1ib3R0b206NzBweDsiPg0KPC9kaXY+DQoNCiMjIEdlbmVyYWwgc3RyZW5ndGggb2YgZDxzdWI+bWlzbWF0Y2g8L3N1Yj4gDQoNCkVzdGltYXRlZCBtZWFuIGQ8c3ViPm1pc21hdGNoPC9zdWI+IGFjcm9zcyBhbGwgc3R1ZGllcyBieSBwaHlsb2dlbmV0aWMgcmFuZG9tIG1vZGVsICh1c2luZyBgTUNNQ2dsbW1gIGZ1bmN0aW9uKS48YnI+DQoNClRoZSBtb2RlbCBpbmNsdWRlZCBmb2xsb3dpbmcgUmFuZG9tIGVmZmVjdHMgZXN0aW1hdGVzOiANCg0KKiBgU3R1ZHkuSURgOiBQcmltYXJ5IHN0dWRpZXMNCg0KKiBgc3AxLm5hbWVgOiBQaHlsb2dlbnkgb2YgcGFyZW50YWwgc3BlY2llcw0KDQoqIGBDcm9zcy5JRGA6IFBhcmVudGFsIHN0cmFpbiB1c2VkIGluIHRoZSBjcm9zc2luZy4gRGlzY3JpbWluYXRlIGludHJhc3BlY2lmaWMgcG9wdWxhdGlvbnMNCg0KKiBgSHlicmlkYDogQ3Jvc3NpbmcgZGlyZWN0aW9uDQoNCiogYFNFLnVuaXRzYDogU2FtcGxpbmcgdmFyaWFuY2Ugb2YgZWZmZWN0IHNpemUNCg0KYGBge3J9DQoNCiMrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrIw0KcHJpbnQoIlBoeWxvZ2VuZXRpYyB0cmVlIGZvciBtY21jZ2xtbSIpDQojKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyMNCg0KIyBjb21wdXRlIGJyYW5jaCBsZW5ndGhzIG9mIHRyZWUNCnBoeWxvX2JyYW5jaCA8LSByZWFkLnRyZWUoZmlsZSA9ICIuLi9kYXRhL3BoeWxvLm5vdmVsdHkudHJlIikgJT4lDQogIGNvbXB1dGUuYnJsZW4obWV0aG9kID0gIkdyYWZlbiIsIHBvd2VyID0gMSkNCnBsb3QucGh5bG8ocGh5bG9fYnJhbmNoLCBjZXggPSAwLjcpDQoNCiMgIyBzYXZpbmcgcGh5bG9nZW5laWMgbWF0cml4DQojIHBoeWxvX2NvciA8LSB2Y3YocGh5bG9fYnJhbmNoLCBjb3IgPSBUKQ0KIyANCiMgIyBnZW5lcmF0aW5nIGludmVyc2UgcGh5bG9nZW5ldGljIG1hdHJpeCBmb3IgTUNNQ2dsbW0NCiMgcGh5bG9fYnJhbmNoJG5vZGUubGFiZWwgPC0gTlVMTA0KIyBwaHlsb19NQ01DIDwtIE1DTUNnbG1tOjppbnZlcnNlQShwaHlsb19icmFuY2gsIG5vZGVzID0gIkFMTCIsIHNjYWxlID0gVFJVRSkkQWludg0KDQojIHBoeWxtaXggPC1NQ01DZ2xtbSgNCiMgICBmaXhlZCA9IE1pc21hdGNoIH4gIDEsDQojICAgIyBpZGgoU0UpOnVuaXRzIHwgd2VpZ2h0IGJ5IFNFIG9mIGVmZmVjdCBzaXplDQojICAgcmFuZG9tID0gfiBTdHVkeS5JRCArIHNwMS5uYW1lICsgQ3Jvc3MuSUQgKyBIeWJyaWQsDQojICAgdmVyYm9zZSA9IEZBTFNFLA0KIyAgIGdpbnZlcnNlID0gbGlzdChzcDEubmFtZSA9IHBoeWxvX01DTUMpLA0KIyAgIG5pdHQgPSA2MDAwMCwgICMgSW5jcmVhc2UgdGhlIG51bWJlciBvZiBpdGVyYXRpb25zLCBkZWZhdWx0IGlzIDEzMDAwDQojICAgYnVybmluID0gNTAwMCwgICMgSW5jcmVhc2UgdGhlIG51bWJlciBvZiBidXJuaW4sIGRlZmF1bHQgaXMgMzAwMA0KIyAgIGRhdGEgPSBkYXQNCiMgKQ0KIyBzYXZlUkRTKHBoeWxtaXgsIGZpbGUgPSAiLi4vQW5hbHlzaXMvbWlzbWF0Y2gub2JqIikNCg0KcGh5bG1peCA8LSByZWFkUkRTKCIuLi9BbmFseXNpcy9taXNtYXRjaC5vYmoiKQ0KDQojKysrKysrKysrKysrKysrKysrKysrKysrKysrIw0KIyBGaXhlZCBlZmZlY3RzIG91dHB1dCANCiMrKysrKysrKysrKysrKysrKysrKysrKysrKysjDQpnZXRfZml4ZWQuTUNNQ2dsbW0oc3VtbWFyeShwaHlsbWl4KSRzb2x1dGlvbnMpICU+JQ0KICBkcGx5cjo6c2VsZWN0KCJGYWN0b3JzIiwgIkVzdGltYXRlcyIsICI5NSUgY3JlZGlibGUgaW50ZXJ2YWwiLCAiUCIsICJEZXNjcmlwdGlvbiIpICU+JQ0KICBrYWJsZSgiaHRtbCIsIGRpZ2l0cyA9IDMsIGNhcHRpb24gPSAiRml4ZWQgZWZmZWN0cyBlc3RpbWF0ZXMiKSAlPiUgDQogIGthYmxlX3N0eWxpbmcoInN0cmlwZWQiLCBwb3NpdGlvbiA9ICJsZWZ0IikNCg0KIysrKysrKysrKysrKysrKysrKysrKysrKysrKyMNCiMgUmFuZG9tIGVmZmVjdHMgb3V0cHV0IA0KIysrKysrKysrKysrKysrKysrKysrKysrKysrKyMNCiMgdHJhbnNmb3JtYXRpb24gZm9yIHZhcmFpbmNlDQpnZXRfcmFuZG9tLk1DTUNnbG1tKHN1bW1hcnkocGh5bG1peCRWQ1YpKSAlPiUNCiAga2FibGUoImh0bWwiLCBkaWdpdHMgPSAyLCBjYXB0aW9uID0gIlJhbmRvbSBlZmZlY3RzIGVzdGltYXRlcyIpICU+JSANCiAga2FibGVfc3R5bGluZygic3RyaXBlZCIsIHBvc2l0aW9uID0gImxlZnQiKQ0KDQpgYGANCkV2ZW4gZGF0YSBpbmNsdWRlZCBxdWl0ZSBsYXJnZSBkPHN1Yj5taXNtYXRjaDwvc3ViPiwgb3ZlcmFsbCBpdCBkaWQgbm90IGRpZmZlciBmcm9tIDAuIFlldCwgdGhlIGVzdGltYXRlICjOsiAgPSA0LjQxLCBDSSA9IC0zLjA1IOKAkyAxMC4yOSkgaXMgc3RpbGwgbXVjaCBsYXJnZXIgdGhhbiAgcHJldmlvdXNseSByZXBvcnRlZCBtZWFuIGQ8c3ViPm1pc21hdGNoPC9zdWI+IDAuNiBbVGhvbXBzb24gZXQgYWwuIDIwMTldKGh0dHBzOi8vd3d3LmJpb3J4aXYub3JnL2NvbnRlbnQvMTAuMTEwMS84MTg2NTh2MS5mdWxsI2Rpc3AtZm9ybXVsYS0xKS4gVGhpcyBpcyBwcmVzdW1hYmx5IGJlY2F1c2Ugbm92ZWx0eSBpbiBwaGVub3R5cGljIG1lYW5zLCB3aGljaCBzaG91bGQgaW5jcmVhc2UgZDxzdWI+bWlzbWF0Y2g8L3N1Yj4sIGlzIG11Y2ggbW9yZSBmcmVxdWVudCBpbiBvdXIgZGF0YSBjb21wYXJlZCB0byBbVGhvbXBzb24gZXQgYWwuIDIwMTldKGh0dHBzOi8vd3d3LmJpb3J4aXYub3JnL2NvbnRlbnQvMTAuMTEwMS84MTg2NTh2MS5mdWxsI2Rpc3AtZm9ybXVsYS0xKS4NCg0KPGRpdiBzdHlsZT0ibWFyZ2luLWJvdHRvbTo3MHB4OyI+DQo8L2Rpdj4NCg0KIyMgRmFjdG9ycyBhZmZlY3RpbmcgIGQ8c3ViPm1pc21hdGNoPC9zdWI+DQoNCldlIGFza2VkIGlmIGFueSBzcGVjaWVzLWxldmVsIG1vZGVyYXRvcnMgKEdlbmV0aWMgZGl2ZXJnZW5jZSBiZXR3ZWVuIHBhcmVudHMsIGBHZW5ldC5kaXZlcmdlbmNlYDsgVmlhYmlsaXR5IG9mIHJlY2lwcm9jYWwgY3Jvc3MsIGBSZWNpcHJvY2FsYDsgSGV0ZXJvZ2FtZXRpYyBzZXgsIGBIZXRlcm8uc2V4YDsgUGFyZW50cycgZGlzdHJpYnV0aW9uIG92ZXJsYXAsIGBEaXN0cmlidXRpb25gKSBpbmZsdWVuY2UgZDxzdWI+bWlzbWF0Y2g8L3N1Yj4gdmFsdWVzIGJ5IHBoeWxvZ2VuZXRpYyByYW5kb20gbW9kZWwuIFJhbmRvbSBlZmZlY3RzIHdlcmUgaWRlbnRpY2FsIGFzIFthYm92ZV0gKCMjIEdlbmVyYWwgcGF0dGVybiBvZiBtaXNtYXRjaCBkPHN1Yj5taXNtYXRjaDwvc3ViPikuDQpgYGB7cn0NCg0KZGF0MyA8LSBkYXQgJT4lDQogIGRyb3BfbmEoR2VuZXQuZGl2ZXJnZW5jZSwgUmVjaXByb2NhbCwgSGV0ZXJvLnNleCwgRGlzdHJpYnV0aW9uKQ0KDQojIHBoeWxtaXggPC1NQ01DZ2xtbSgNCiMgICBmaXhlZCA9IE1pc21hdGNoIH4gIEdlbmV0LmRpdmVyZ2VuY2UgKyBSZWNpcHJvY2FsICsgSGV0ZXJvLnNleCArIERpc3RyaWJ1dGlvbiwNCiMgICAjIGlkaChTRSk6dW5pdHMgfCB3ZWlnaHQgYnkgU0Ugb2YgZWZmZWN0IHNpemUNCiMgICByYW5kb20gPSB+IFN0dWR5LklEICsgc3AxLm5hbWUgKyBDcm9zcy5JRCArIEh5YnJpZCwNCiMgICB2ZXJib3NlID0gRkFMU0UsDQojICAgZ2ludmVyc2UgPSBsaXN0KHNwMS5uYW1lID0gcGh5bG9fTUNNQyksDQojICAgbml0dCA9IDYwMDAwLCAgIyBJbmNyZWFzZSB0aGUgbnVtYmVyIG9mIGl0ZXJhdGlvbnMsIGRlZmF1bHQgaXMgMTMwMDANCiMgICBidXJuaW4gPSA1MDAwLCAgIyBJbmNyZWFzZSB0aGUgbnVtYmVyIG9mIGJ1cm5pbiwgZGVmYXVsdCBpcyAzMDAwDQojICAgZGF0YSA9IGRhdDMNCiMgKQ0KIyBzYXZlUkRTKHBoeWxtaXgsIGZpbGUgPSAiLi4vQW5hbHlzaXMvbWlzbWF0Y2gucmVnLm9iaiIpDQoNCnBoeWxtaXggPC0gcmVhZFJEUygiLi4vQW5hbHlzaXMvbWlzbWF0Y2gucmVnLm9iaiIpDQoNCiMrKysrKysrKysrKysrKysrKysrKysrKysrKysjDQojIEZpeGVkIGVmZmVjdHMgb3V0cHV0IA0KIysrKysrKysrKysrKysrKysrKysrKysrKysrKyMNCmdldF9maXhlZC5NQ01DZ2xtbShzdW1tYXJ5KHBoeWxtaXgpJHNvbHV0aW9ucykgICU+JQ0KICBkcGx5cjo6c2VsZWN0KCJGYWN0b3JzIiwgIkVzdGltYXRlcyIsICI5NSUgY3JlZGlibGUgaW50ZXJ2YWwiLCAiUCIsICJEZXNjcmlwdGlvbiIpICU+JQ0KICBrYWJsZSgiaHRtbCIsIGRpZ2l0cyA9IDMsIGNhcHRpb24gPSAiRml4ZWQgZWZmZWN0cyBlc3RpbWF0ZXMiKSAlPiUgDQogIGthYmxlX3N0eWxpbmcoInN0cmlwZWQiLCBwb3NpdGlvbiA9ICJsZWZ0IikNCg0KIysrKysrKysrKysrKysrKysrKysrKysrKysrKyMNCiMgUmFuZG9tIGVmZmVjdHMgb3V0cHV0IA0KIysrKysrKysrKysrKysrKysrKysrKysrKysrKyMNCiMgdHJhbnNmb3JtYXRpb24gZm9yIHZhcmFpbmNlDQpnZXRfcmFuZG9tLk1DTUNnbG1tKHN1bW1hcnkocGh5bG1peCRWQ1YpKSAlPiUNCiAgICBrYWJsZSgiaHRtbCIsIGRpZ2l0cyA9IDIsIGNhcHRpb24gPSAiUmFuZG9tIGVmZmVjdHMgZXN0aW1hdGVzIikgJT4lIA0KICAgIGthYmxlX3N0eWxpbmcoInN0cmlwZWQiLCBwb3NpdGlvbiA9ICJsZWZ0IikNCg0KYGBgDQpOb25lIG9mIHNwZWNpZXMgbGV2ZWwgbW9kZXJhdG9ycyBkaWQgbm90IGluZmx1ZW5jZSBkPHN1Yj5taXNtYXRjaDwvc3ViPiwgYXMgW1Rob21wc29uIGV0IGFsLiAyMDE5XShodHRwczovL3d3dy5iaW9yeGl2Lm9yZy9jb250ZW50LzEwLjExMDEvODE4NjU4djEuZnVsbCNkaXNwLWZvcm11bGEtMSkgc2hvd2VkLiANCg0KDQo8ZGl2IHN0eWxlPSJtYXJnaW4tYm90dG9tOjE4MHB4OyI+DQo8L2Rpdj4NCiMgTWV0YS1hbmFseXNpcyBmb3IgcGhlbm90eXBpYyB2YXJpYXRpb24gKHVzaW5nIGxuVlIpDQoNCiMjIEFsbGlnbiBwYXJlbnRhbCBzcGVjaWVzIGFjY29yZGluZyB0byBwaGVub3R5cGljIHZhcmlhdGlvbg0KDQpUbyBpbnZlc3RpZ2F0ZSBwYXRlcm5hbCBlZmZlY3QgaW4gaHlicmlkcyB1c2luZyBkaWZmZXJlbmNlIGluIHZhcmlhbmNlIGJldHdlZW4gcmVjaXByb2NhbCBjcm9zcywgaXQncyBiZXR0ZXIgdG8gYWxsaWduIHNwZWNpZXMgd2l0aCBsYXJnZXIgcGhlbm90eXBpYyB2YXJpYW5jZSAoPGk+c3BMTDxzdWI+VjI8L3N1Yj48L2k+KSBhbmQgc21hbGxlciBDViAoPGk+c3BTUzxzdWI+VjI8L3N1Yj48L2k+KSBpbiBlYWNoIHRyYWl0cy4gTmFtZSBvZiBoeWJyaWRzIHdpbGwgYmUgY2hhbmdlZCBhY2NvcmRpbmcgdG8gY2hhbmdlIGluIG5hbWVzIG9mIHBhcmVudGFsIHNwZWNpZXMgKDxpPmh5YnJpZExTPHN1Yj5WMjwvc3ViPjwvaT4gJiA8aT5oeWJyaWRTTDxzdWI+VjI8L3N1Yj48L2k+KS4gIA0KDQpgYGB7cn0NCg0KIysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysjDQojIHNwMSA+PSBzcDIgaW4gcGhlbm90eXBpYyB2YXJpYXRpb24NCiMrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrIw0KIyBleHRyYWN0DQpzcDFzcDIudmFyIDwtIG9yaWdpbmFsLmRhdCAlPiUNCiAgZmlsdGVyKFNELnNwMSA+PSBTRC5zcDIpICMgZmlsdGVyaW5nIGFjY29yZGluZyB0byBDViBvZiBwYXJlbnRhbHMNCiMgY2hhbmdlIGNvbHVtbiBuYW1lIGZyb20gc3AxIG9yIHNwMiAtPiBzcEwgb3Igc3BTDQpuYW1lcyhzcDFzcDIudmFyKSA8LSBnc3ViKCIxIiwgIkwiLCBuYW1lcyhzcDFzcDIudmFyKSkNCm5hbWVzKHNwMXNwMi52YXIpIDwtIGdzdWIoIjIiLCAiUyIsIG5hbWVzKHNwMXNwMi52YXIpKQ0KDQojKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyMNCiMgc3AxIDwgc3AyIGluIHBoZW5vdHlwaWMgdmFyaWF0aW9uDQojKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyMNCiMgZXh0cmFjdA0Kc3Ayc3AxLnZhciA8LSBvcmlnaW5hbC5kYXQgJT4lDQogIGZpbHRlcihTRC5zcDEgPCBTRC5zcDIpDQojIGNoYW5nZSBjb2x1bW4gbmFtZSBmcm9tIHNwMSBvciBzcDIgLT4gc3BTIG9yIHNwTA0KbmFtZXMoc3Ayc3AxLnZhcikgPC0gZ3N1YigiMSIsICJTIiwgbmFtZXMoc3Ayc3AxLnZhcikpDQpuYW1lcyhzcDJzcDEudmFyKSA8LSBnc3ViKCIyIiwgIkwiLCBuYW1lcyhzcDJzcDEudmFyKSkNCg0KIysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysjDQojIGNvbWJpbmUgZGF0YXNldCAmIHNvcnQgYnkgRVMuSUQgDQojKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyMNCmJpbmRfcm93cyhzcDFzcDIudmFyLCBzcDJzcDEudmFyKSAlPiUNCiAgYXJyYW5nZShFUy5JRCkgJT4lDQogIHdyaXRlLmNzdigiLi4vZGF0YS9kYXQudmFyLmNzdiIsIHF1b3RlPUYscm93Lm5hbWVzID0gRikNCg0KYGBgDQo8IS0tIERhdGEgc2V0IGNyZWF0ZWQgaGVyZSwgYGRhdC52YXIuY3N2YCwgaXMgdXNlZCBpbiBjYWxjdWxhdGluZyBlZmZlY3Qgc2l6ZXMgZm9yIGFuYWx5c2VzIGludmVzdGlnYXRpbmcgW3BoZW5vdHlwaWMgdmFyaWF0aW9uXSgjbWV0YS1hbmFseXNpcy1mb3ItcGhlbm90eXBpYy12YXJpYXRpb24pIGFuZCBbbm92ZWx0eSBpbiBwaGVub3R5cGljIHZhcmlhYmlsaXRpZXNdKCNub3ZlbC12YXJpYWJpbGl0eS1leHByZXNzaW9uKS4gLS0+DQoNCg0KIyMgRWZmZWN0IHNpemUgY2FsY3VsYXRpb24NCg0KV2UgcXVhbnRpZmllZCByZWxhdGl2ZSBwaGVub3R5cGljIHZhcmlhYmlsaXR5IG9mIGh5YnJpZHMgYW5kIHRoZSBwYXJlbnQgd2l0aCBsYXJnZSB2YXJpYWJpbGl0eSAoPGk+c3BMTDxzdWI+VjI8L3N1Yj48L2k+KSB0byB0aGUgcGFyZW50IHdpdGggc21hbGwgdmFyaWFiaWxpdHkgKDxpPnNwU1M8c3ViPlYyPC9zdWI+PC9pPiksIGJ5IHVzaW5nIFtsblZSXShodHRwczovL2Jlc2pvdXJuYWxzLm9ubGluZWxpYnJhcnkud2lsZXkuY29tL2RvaS9mdWxsLzEwLjExMTEvMjA0MS0yMTBYLjEyMzA5KS4gKipXZSBjb21wYXJlZCB2YXJpYW5jZSBpdHNlbGYqKiwgYW5kIGRpZCBub3QgY29udHJvbGwgbWVhbi12YXJpYW5jZSByZWxhdGlvbnNoaXAuIDxicj4NCkVmZmVjY3Qgc2l6ZSB3YXMgY2FsY3VsYXRlZCBieSB1c2luZyBgZXNjYWxjYCBmdW5jdGlvbiBpbiBgbWV0YWZvcmAgcGFja2FnZSANCg0KYGBge3J9DQoNCiMgbG9hZCBzcExTIGZpbGVzDQpkYXQgPC0gcmVhZC5jc3YoIi4uL2RhdGEvZGF0LnZhci5jc3YiLCBoZWFkID0gVFJVRSkNCg0KIyBPcmRlciBieSB0YXhvbg0KZGF0JHRheGEgPC0gb3JkZXJlZCgNCiAgZGF0JHRheGEsDQogIGxldmVscyA9IGMoIk5ldXJvcHRlcmEiLCAiQ29sZW9wdGVyYSIsICJEaXB0ZXJhIiwgIkxlcGlkb3B0ZXJhIiwgIk9ydGhvcHRlcmEiLCAiQXZlcyIsICJSb2RlbnRpYSIsICJBbnVyYSIsICJDaWNobGlmb3JtZXMiKQ0KICApDQoNCnZhci5kaWYgPC0gZm9yZWFjaCgNCiAgY3IgPSBjKCJoeWJMUyIsICJoeWJTTCIsICJzcEwiKSwgDQogIC5jb21iaW5lID0gYHJiaW5kYA0KICApICVkbyUgew0KICAgIGVzY2FsYygNCiAgICAgIG1lYXN1cmUgPSAiVlIiLA0KICAgICAgIyBOIG9mIGh5YnJpZHMNCiAgICAgIG4xaSA9IGRhdFssIHBhc3RlKCJOIiwgY3IsIHNlcCA9ICIuIildLA0KICAgICAgIyBOIG9mIHBhcmVudGFscw0KICAgICAgbjJpID0gZGF0WywgIk4uc3BTIl0sDQogICAgICAjIE1lYW4gb2YgaHlicmlkcw0KICAgICAgbTFpID0gZGF0WywgcGFzdGUoIk1uIiwgY3IsIHNlcCA9ICIuIildLA0KICAgICAgIyBNZWFuIG9mIHBhcmVudGFscw0KICAgICAgbTJpID0gZGF0WywgIk1uLnNwUyJdLA0KICAgICAgIyBTRCBvZiBoeWJyaWRzXQ0KICAgICAgc2QxaSA9IGRhdFssIHBhc3RlKCJTRCIsIGNyLCBzZXAgPSAiLiIpXSwNCiAgICAgICMgU0Qgb2YgcGFyZW50YWxzDQogICAgICBzZDJpID0gZGF0WywgIlNELnNwUyJdLA0KICAgICAgZGF0YSA9IGRhdA0KICAgICAgKSAlPiUNCiAgICByZW5hbWUobG5WUi5lcyA9IHlpLCBsblZSLnN2ID0gdmkpICU+JQ0KICAgIG11dGF0ZShjcm9zcyA9IGNyKQ0KICAgIH0gJT4lDQogIGRyb3BfbmEobG5WUi5lcykgJT4lDQogIGFycmFuZ2UoRVMuSUQpICU+JQ0KICBsZWZ0X2pvaW4oLiwgZGF0KQ0KDQp3cml0ZS5jc3YodmFyLmRpZiwgIi4uL2RhdGEvbG5WUi5FUy5nZW5lcmFsLmNzdiIsIHJvdy5uYW1lcyA9IEYpDQoNCmBgYA0KDQojIyBGdW5uZWwgcGxvdHMNCg0KYGBge3J9DQoNCnJlcyA8LSBybWEoeWkgPSBsblZSLmVzLCB2aSA9IGxuVlIuc3YsIGRhdGEgPSB2YXIuZGlmLCBtZXRob2Q9IkZFIikNCg0KIyMgc2V0IHVwIDJ4MiBhcnJheSBmb3IgcGxvdHRpbmcNCnBhcihtZnJvdz1jKDIsMikpDQojIyBkcmF3IGZ1bm5lbCBwbG90cw0KZnVubmVsKHJlcywgbWFpbj0iU3RhbmRhcmQgRXJyb3IiLCB4bGltID0gYygtNSwgNSkpDQpmdW5uZWwocmVzLCB5YXhpcz0idmkiLCBtYWluPSJTYW1wbGluZyBWYXJpYW5jZSIsIHhsaW0gPSBjKC01LCA1KSkNCmZ1bm5lbChyZXMsIHlheGlzPSJzZWludiIsIG1haW49IkludmVyc2UgU3RhbmRhcmQgRXJyb3IiLCB4bGltID0gYygtNSwgNSkpDQpmdW5uZWwocmVzLCB5YXhpcz0idmludiIsIG1haW49IkludmVyc2UgU2FtcGxpbmcgVmFyaWFuY2UiLCB4bGltID0gYygtNSwgNSkpDQoNCmBgYA0KDQoNCg0KIyMgSnVnZGluZyBub3ZlbHR5IGluIHBoZW5vdHlwaWMgdmFyaWFiaWxpdGllcw0KDQpgYGB7cn0NCg0KIyBsb2FkIHNwTFMgZmlsZXMNCmRhdCA8LSByZWFkLmNzdigiLi4vZGF0YS9kYXQudmFyLmNzdiIsIGhlYWQgPSBUUlVFKQ0KDQojKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyMNCiMgRGlmZmVyZW5jZSBiZXR3ZWVuIGxhcmdlciBzcGVjaWVzIChzcEwpIGFuZCBoeWJyaWRzIA0KIysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysjDQoNCmZvciAoaSBpbiBjKCJzcEwiKSkgeyAjIGlkZW50aWZ5IHR5cGUgb2YgaHlicmlkcw0KICBmb3IgKGNyIGluIGMoImh5YkxTIiwgImh5YlNMIikpIHsgIyBpZGVudGlmeSB0eXBlIG9mIHBhcmVudGFscw0KICAgIGFzc2lnbigNCiAgICAgIHBhc3RlKGNyLCBpLCBzZXAgPSAiXyIpLA0KICAgICAgICBlc2NhbGMoDQogICAgICAgICAgbWVhc3VyZSA9ICJWUiIsDQogICAgICAgICAgIyBOIG9mIGh5YnJpZHMNCiAgICAgICAgICBuMWkgPSBkYXRbLCBwYXN0ZSgiTiIsIGksIHNlcCA9ICIuIildLA0KICAgICAgICAgICMgTiBvZiBwYXJlbnRhbHMNCiAgICAgICAgICBuMmkgPSBkYXRbLCBwYXN0ZSgiTiIsIGNyLCBzZXAgPSAiLiIpXSwNCiAgICAgICAgICAjIE1lYW4gb2YgaHlicmlkcw0KICAgICAgICAgIG0xaSA9IGRhdFssIHBhc3RlKCJNbiIsIGksIHNlcCA9ICIuIildLA0KICAgICAgICAgICMgTWVhbiBvZiBwYXJlbnRhbHMNCiAgICAgICAgICBtMmkgPSBkYXRbLCBwYXN0ZSgiTW4iLCBjciwgc2VwID0gIi4iKV0sDQogICAgICAgICAgIyBTRCBvZiBoeWJyaWRzDQogICAgICAgICAgc2QxaSA9IGRhdFssIHBhc3RlKCJTRCIsIGksIHNlcCA9ICIuIildLA0KICAgICAgICAgICMgU0Qgb2YgcGFyZW50YWxzDQogICAgICAgICAgc2QyaSA9IGRhdFssIHBhc3RlKCJTRCIsIGNyLCBzZXAgPSAiLiIpXSwNCiAgICAgICAgICBkYXRhID0gZGF0DQogICAgICAgICAgKSAlPiUNCiAgICAgICAgICBzZWxlY3QoRVMuSUQsIHlpLCB2aSkgJT4lDQogICAgICAgICAgcmVuYW1lKCJsblZSLmVzIiA9ICJ5aSIsICJsbkNWUi5zdiIgPSAidmkiKSAlPiUgDQogICAgICAgIG11dGF0ZSgNCiAgICAgICAgICAjIGRpcmVjdGlvbiBvZiB0cmFuc2dyZXNzdmUgc2VncmVnYXRpb24gLSBncmVhdGVyIHRoYW4gcGFyZW50DQogICAgICAgICAgZGlyZWN0aW9uID0gIisiLA0KICAgICAgICAgICMgU0UgZm9yIGxvZ2lzdGljIGRpc3RyaWJ1dGlvbiwgZm9yIHRoZSB3ZWlnaHRlZCBiaW5vbWlhbCByZWdyZXNzaW9uDQogICAgICAgICAgIyBTRSA9IHBpL3NxcnQoMyoobl9lICsgbl9jKSkNCiAgICAgICAgICBTRSA9IHBpL3NxcnQoMyooDQogICAgICAgICAgICBkYXRbLCBwYXN0ZSgiTiIsIGksIHNlcCA9ICIuIildICsgZGF0WywgcGFzdGUoIk4iLCBjciwgc2VwID0gIi4iKV0NCiAgICAgICAgICApKQ0KICAgICAgICApDQogICAgKQ0KICB9DQp9DQoNCiMrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrIw0KIyBEaWZmZXJlbmNlIGJldHdlZW4gaHlicmlkcyBhbmQgc21hbGxlciBzcGVjaWVzIChzcFMpDQojKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyMNCg0KZm9yIChpIGluIGMoImh5YkxTIiwgImh5YlNMIikpIHsgIyBpZGVudGlmeSB0eXBlIG9mIGh5YnJpZHMNCiAgZm9yIChjciBpbiBjKCJzcFMiKSkgeyAjIGlkZW50aWZ5IHR5cGUgb2YgcGFyZW50YWxzDQogICAgYXNzaWduKA0KICAgICAgcGFzdGUoaSwgY3IsIHNlcCA9ICJfIiksDQogICAgICAgIGVzY2FsYygNCiAgICAgICAgICBtZWFzdXJlID0gIlZSIiwNCiAgICAgICAgICAjIE4gb2YgaHlicmlkcw0KICAgICAgICAgIG4xaSA9IGRhdFssIHBhc3RlKCJOIiwgaSwgc2VwID0gIi4iKV0sDQogICAgICAgICAgIyBOIG9mIHBhcmVudGFscw0KICAgICAgICAgIG4yaSA9IGRhdFssIHBhc3RlKCJOIiwgY3IsIHNlcCA9ICIuIildLA0KICAgICAgICAgICMgTWVhbiBvZiBoeWJyaWRzDQogICAgICAgICAgbTFpID0gZGF0WywgcGFzdGUoIk1uIiwgaSwgc2VwID0gIi4iKV0sDQogICAgICAgICAgIyBNZWFuIG9mIHBhcmVudGFscw0KICAgICAgICAgIG0yaSA9IGRhdFssIHBhc3RlKCJNbiIsIGNyLCBzZXAgPSAiLiIpXSwNCiAgICAgICAgICAjIFNEIG9mIGh5YnJpZHMNCiAgICAgICAgICBzZDFpID0gZGF0WywgcGFzdGUoIlNEIiwgaSwgc2VwID0gIi4iKV0sDQogICAgICAgICAgIyBTRCBvZiBwYXJlbnRhbHMNCiAgICAgICAgICBzZDJpID0gZGF0WywgcGFzdGUoIlNEIiwgY3IsIHNlcCA9ICIuIildLA0KICAgICAgICAgIGRhdGEgPSBkYXQNCiAgICAgICAgICApICU+JQ0KICAgICAgICAgIHNlbGVjdChFUy5JRCwgeWksIHZpKSAlPiUNCiAgICAgICAgICByZW5hbWUoImxuVlIuZXMiID0gInlpIiwgImxuQ1ZSLnN2IiA9ICJ2aSIpICU+JSANCiAgICAgICAgbXV0YXRlKA0KICAgICAgICAgICMgZGlyZWN0aW9uIG9mIHRyYW5zZ3Jlc3N2ZSBzZWdyZWdhdGlvbiAtIHNtYWxsZXIgdGhhbiBwYXJlbnQNCiAgICAgICAgICBkaXJlY3Rpb24gPSAiLSIsDQogICAgICAgICAgIyBTRSBmb3IgbG9naXN0aWMgZGlzdHJpYnV0aW9uLCBmb3IgdGhlIHdlaWdodGVkIGJpbm9taWFsIHJlZ3Jlc3Npb24NCiAgICAgICAgICAjIFNFID0gcGkvc3FydCgzKihuX2UgKyBuX2MpKQ0KICAgICAgICAgIFNFID0gcGkvc3FydCgzKigNCiAgICAgICAgICAgIGRhdFssIHBhc3RlKCJOIiwgaSwgc2VwID0gIi4iKV0gKyBkYXRbLCBwYXN0ZSgiTiIsIGNyLCBzZXAgPSAiLiIpXQ0KICAgICAgICAgICkpDQogICAgICAgICkNCiAgICApDQogIH0NCn0NCg0KDQojKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyMNCiMgRGF0YSBvdXRwdXQNCiMrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrIw0KDQpiaW5kX3Jvd3MoDQogICMjIERpZmZlcmVuY2Ugd2l0aCBtb3RoZXIgc3BlY2llcyAjIyMNCiAgYmluZF9yb3dzKGh5YkxTX3NwTCwgaHliU0xfc3BTKSAlPiUNCiAgICBtdXRhdGUocGFyZW50YWwgPSAiTW90aGVyIiksDQogICMjIERpZmZlcmVuY2Ugd2l0aCBmYXRoZXIgc3BlY2llcyAjIyMNCiAgYmluZF9yb3dzKGh5YkxTX3NwUywgaHliU0xfc3BMKSAlPiUNCiAgICBtdXRhdGUocGFyZW50YWwgPSAiRmF0aGVyIikNCiAgKSAlPiUNCiAgZHJvcF9uYShsblZSLmVzKSAlPiUNCiAgbGVmdF9qb2luKC4sIGRhdCkgJT4lDQogICMgQXNzaWduIG5vdmVsIHZhcmlhYmlsaXR5IHRvIDEsIG5vbi1ub3ZlbCB2YXJpYWJpbGl0eSB0byAwIGZvciBlYWNoIGVmZmVjdCBzaXplDQogIG11dGF0ZShOb3ZlbHR5ID0gaWZlbHNlKGxuVlIuZXMgPCAwLCAxLCAwKSkgJT4lDQogICMjIEpvaW4gd2l0aCBtZXRhZGF0YSAjIyMNCiAgbGVmdF9qb2luKA0KICAgIC4sDQogICAgcmVhZC54bHN4KA0KICAgICAgIi4uL2RhdGEvb3JpZ2luYWwuZGF0YS54bHN4Iiwgc2hlZXQgPSAiU3BlY2llcy5sZXZlbC5tb2RlcmF0b3JzIg0KICAgICAgKQ0KICAgICkgJT4lDQogIG11dGF0ZV9hdCh2YXJzKGNvbnRhaW5zKCJkaXZlcmdlbmNlIikpLCBhcy5udW1lcmljKSAlPiUNCiAgbXV0YXRlX2F0KHZhcnMoY29udGFpbnMoImRpdmVyZ2VuY2UiKSksIHNjYWxlKSAlPiUNCiAgYXMuZGF0YS5mcmFtZSAlPiUNCiAgc2VsZWN0KC10cmFpdCkgJT4lDQogIGRyb3BfbmEoSGV0ZXJvLnNleCwgdHJhaXQudHlwZSwgR2VuZXQuZGl2ZXJnZW5jZSkgJT4lDQogICMgb3JkZXIgdGF4b24NCiAgd2l0aGluKA0KICAgIHRheGEgPC0gb3JkZXJlZCgNCiAgICAgIHRheGEsDQogICAgICBsZXZlbHMgPSBjKCJOZXVyb3B0ZXJhIiwgIkNvbGVvcHRlcmEiLCAiRGlwdGVyYSIsICJMZXBpZG9wdGVyYSIsICJPcnRob3B0ZXJhIiwgIkF2ZXMiLCAiUm9kZW50aWEiLCAiQW51cmEiLCAiQ2ljaGxpZm9ybWVzIikNCiAgICAgICkNCiAgICApICU+JQ0KICBtdXRhdGVfaWYoaXMuY2hhcmFjdGVyLCBhcy5mYWN0b3IpICU+JQ0KICAjIEluc2VjdCBvciBubw0KICBtdXRhdGUoDQogICAgaW5zZWN0ID0gaWZlbHNlKHRheGEgJWluJSBjKCJBdmVzIiwgIlJvZGVudGlhIiwgIkFudXJhIiwgIkNpY2hsaWZvcm1lcyIpLCAibm8iLCAiaW5zZWN0IiksDQogICkgJT4lDQogIHdyaXRlLmNzdigiLi4vZGF0YS9sblZSLkVTLk5vdmVsdHkuY3N2Iiwgcm93Lm5hbWVzID0gRikNCg0KYGBgDQoNCg0KIyMgUmVsb2FkIGRhdGEgJiBQcmVwYXJlIHBoeWxvZ2VuZXRpYyB0cmVlDQoNCmBgYHtyLCBmaWcuaGVpZ2h0ID0gNi41fQ0KDQojIExvYWQgZWZmZWN0IHNpemVzDQp2YXIuZGlmIDwtIHJlYWQuY3N2KCIuLi9kYXRhL2xuVlIuRVMuZ2VuZXJhbC5jc3YiLCBoZWFkID0gVFJVRSklPiUNCiAgIyBpbmRpY2F0ZSBkYXRhc2V0IGluY2x1ZGluZyBub3ZlbCB2YXJpYWJpbGl0eQ0KICBtdXRhdGUoZGF0YS50eXBlID0gIkFsbHRyYWl0cyIpDQoNCiMgT2JzZXJ2YXRpb25zIHdpdGggbm92ZWwgdmFyaWFiaWxpdHkNCkFsbCA8LSByZWFkLmNzdigiLi4vZGF0YS9sblZSLkVTLm5vdmVsdHkuY3N2IiwgaGVhZCA9IFRSVUUpICU+JQ0KICBmaWx0ZXIobG5WUi5lcyA8IDApICU+JQ0KICBkaXN0aW5jdChFUy5JRCkNCg0KIyBFZmZlY3Qgc2l6ZXMgd2l0aCBub24tbm92ZWwgdmFyaWFiaWxpdHkNCk5vbm92ZWwgPC0gcmVhZC5jc3YoIi4uL2RhdGEvbG5WUi5FUy5nZW5lcmFsLmNzdiIsIGhlYWQgPSBUUlVFKSAlPiUNCiAgZmlsdGVyKCFFUy5JRCAlaW4lIHVuaXF1ZShBbGwkRVMuSUQpKSAlPiUNCiAgIyBpbmRpY2F0ZSBkYXRhc2V0IHdpdGhvdXQgbm92ZWwgdmFyaWFiaWxpdHkNCiAgbXV0YXRlKGRhdGEudHlwZSA9ICJOb25ub3ZlbHRyYWl0cyIpDQoNCiMgY29tYmluZSBkYXRhc2V0IHdpdGgvd2l0aG91dCBub3ZlbCB2YXJpYWJpbGl0eQ0KTm92ZWwuTm9ubm92ZWwgPC0gYmluZF9yb3dzKHZhci5kaWYsIE5vbm92ZWwpICU+JQ0KICBtdXRhdGUobWV0YXVuaXQgPSAgc3RyX2MoZGF0YS50eXBlLCBjcm9zcywgc2VwID0gIl8iKSkgJT4lDQogICMgVXNlIG9ic2VydmF0aW9ucyB3aXRoIGJvdGggcmVjaXByb2NhbCBjcm9zc2VzDQogIGRyb3BfbmEoY29udGFpbnMoIk1uIiksIGNvbnRhaW5zKCJTRCIpKSAlPiUNCiAgIyBJbnNlY3Qgb3Igbm8NCiAgbXV0YXRlKA0KICAgIGluc2VjdCA9IGlmZWxzZSh0YXhhICVpbiUgYygiQ2ljaGxpZm9ybWVzIiwgIkFudXJhIiwgIkF2ZXMiLCAiUm9kZW50aWEiKSwgIm5vIiwgImluc2VjdCIpLA0KICApDQoNCiMrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrIw0KIyBQaHlsb2dlbnkgDQojKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyMNCg0KIyAjIG1hdGNoaW5nIG5hbWVzIGZyb20gb3BlbiB0cmVlIHRheG9ub215DQojIHRheGEgPC0gdG5yc19tYXRjaF9uYW1lcygNCiMgICBuYW1lcyA9IGxldmVscyh2YXIuZGlmJHNwTC5uYW1lKSAlPiUNCiMgICAgIHN0cl9yZXBsYWNlX2FsbCgiXyIsICIgIiksDQojICAgY29udGV4dF9uYW1lID0gIkFuaW1hbHMiDQojICAgKQ0KIyANCiMgIyBDcmVhdGUgdHJlZQ0KIyB0cmVlIDwtIHRvbF9pbmR1Y2VkX3N1YnRyZWUob3R0X2lkcyA9IHRheGEkb3R0X2lkKQ0KIyB0cmVlJHRpcC5sYWJlbCAlPD4lDQojICAgc3RyaXBfb3R0X2lkcyAjIHJlbW92ZSBPVFQgSURzIGZyb20gdGlwIGxhYmVscw0KIyAjIHJhbmRvbWx5IHNvbHZlIG5vbi1iaW5hcnkgcGh5bG9nZW55DQojIHNldC5zZWVkKDYpDQojIGJpbi50cmVlIDwtIG11bHRpMmRpKHRyZWUsIHJhbmRvbSA9IFQpDQojIA0KIyAjIEZpeCBuYW1lcyBvZiB0aXAgbGFiZWxzDQojIGJpbi50cmVlJHRpcC5sYWJlbCAlPD4lIHN0cl9yZXBsYWNlX2FsbCgiRHJ5b3BoeXRlcyIsICJIeWxhIikNCiMgIyBJbmRpY2F0ZSBtaXNtYXRjaCBiZXR3ZWVuIHRpcCBsYWJlbHMgJiBkYXRhc2V0IHNwZWNpZXMgbmFtZXMNCiMgc2V0ZGlmZihsZXZlbHMoYXMuZmFjdG9yKGJpbi50cmVlJHRpcC5sYWJlbCkpLCBsZXZlbHModmFyLmRpZiRzcEwubmFtZSkpDQojIHNldGRpZmYobGV2ZWxzKHZhci5kaWYkc3BMLm5hbWUpLCBsZXZlbHMoYXMuZmFjdG9yKGJpbi50cmVlJHRpcC5sYWJlbCkpKQ0KIyANCiMgd3JpdGUudHJlZShiaW4udHJlZSwgZmlsZT0gIi4uL2RhdGEvcGh5bG8ubG5WUi50cmUiKQ0KDQojIGNvbXB1dGUgYnJhbmNoIGxlbmd0aHMgb2YgdHJlZQ0KcGh5bG9fYnJhbmNoIDwtIHJlYWQudHJlZShmaWxlID0gIi4uL2RhdGEvcGh5bG8ubG5WUi50cmUiKSAlPiUNCiAgY29tcHV0ZS5icmxlbihiaW4udHJlZSwgbWV0aG9kID0gIkdyYWZlbiIsIHBvd2VyID0gMSkNCg0KIyBzYXZpbmcgcGh5bG9nZW5laWMgbWF0cml4DQpwaHlsb19jb3IgPC0gdmN2KHBoeWxvX2JyYW5jaCwgY29yID0gVCkNCg0KIyBOb3RlIG9uZSBvZiB0aGUgdGlwcyBpcyBjYWxsZWQgIkxhdGVzIGNhbGNhcmlmZXIgKGVzdGltYXRlZCkiDQpwaHlsb19icmFuY2gkbm9kZS5sYWJlbCA8LSBOVUxMDQoNCiMgUGxvdCB0cmVlDQpwbG90LnBoeWxvKHBoeWxvX2JyYW5jaCwgY2V4ID0gMC43KQ0KDQpgYGANCg0KPGRpdiBzdHlsZT0ibWFyZ2luLWJvdHRvbTo3MHB4OyI+DQo8L2Rpdj4NCg0KIyMgRG9taW5hbmNlIGluIHBoZW5vdHlwaWMgdmFyaWFiaWxpdHkgKGNvZWZmaWNpZW50IG9mIHZhcmlhdGlvbikNCg0KV2UgY29tcGFyZWQgbWlkcGFyZW50LXZhbHVlIG9mIHBoZW5vdHlwaWMgdmFyaWFiaWxpdHkgYW5kIGh5YnJpZHMnIHBoZW5vdHlwaWMgdmFyaWFiaWxpdHkgYnkgY2FsY3VsYXRpbmcgbG9nIHJhdGlvIG9mIHBoZW5vdHlwaWMgdmFyaWFiaWxpdHkgKGxuVlIpIG9mIG1pZHBhcmVudC12YWx1ZSBhbmQgaHlicmlkcyB0byA8aT5zcFNTPHN1Yj5WPC9zdWI+PC9pPi4gPGJyPiANCg0KSXQncyBzYW1wbGluZyB2YXJpYW5jZSB3YXMgc3Vic3RpdHV0ZSBieSB0aGF0IG9mIDxpPnNwTEw8c3ViPlY8L3N1Yj48L2k+IDxicj4NCg0KV2Ugc3RhdGlzdGljYWxseSBjb21wYXJlZCB0aG9zZSBlZmZlY3Qgc2l6ZXMgdGhyb3VnaCB0aGUgZm9ybWFsIG1ldGEtcmVncmVzc2lvbiBieSB1c2luZyBgcm1hLm12YCBmdW5jdGlvbiBvZiBSIHBhY2thZ2UgYG1ldGFmb3JgIDxicj4NCg0KQWxsIG1ldGEtYW5hbHl0aWMgbW9kZWxzIGluY2x1ZGVkIGZvbGxvd2luZyBSYW5kb20gZWZmZWN0cyBlc3RpbWF0ZXM6IA0KDQoqIGBTdHVkeS5JRGA6IFByaW1hcnkgc3R1ZGllcy4gRGVub3RlZCBhcyAqKlN0dWR5KioNCg0KKiBgQ3Jvc3MuSURgOiBQYXJlbnRhbCBzdHJhaW4gdXNlZCBpbiB0aGUgY3Jvc3NpbmcuIERpc2NyaW1pbmF0ZSBpbnRyYXNwZWNpZmljIHBvcHVsYXRpb25zLiBEZW5vdGVkIGFzICoqY3Jvc3NlZCBzdHJhaW4qKg0KDQoqIGBzcEwubmFtZWA6IFBoeWxvZ2VueSBvZiBwYXJlbnRhbCBzcGVjaWVzICg8aT5zcExMPHN1Yj5NPC9zdWI+PC9pPikuIERlbm90ZWQgYXMgKipzcGVjaWVzIHdpdGggcGh5bG9nZW55KioNCg0KYGBge3J9DQoNCiMrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrIw0KIyBDYWxjdWxhdGUgbWlkcGFyZW50IA0KIysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysjDQptaWRwYXJlbnQgPC0gTm92ZWwuTm9ubm92ZWwgJT4lDQogICBtdXRhdGUoDQogICAgIGxuVlIubWlkcGFyZW50LmVzID0NCiAgICAgICBpZmVsc2UoDQogICAgICAgICBjcm9zcyA9PSAic3BMIiwNCiAgICAgICAgICMgbG9nKFNlL1NjKQ0KICAgICAgICAgbG9nKChTRC5zcEwgKyBTRC5zcFMpLzIpIC0gbG9nKFNELnNwUykgKyAgDQogICAgICAgICAgICMgMS8yKE5lLTEpIC0gMS8yKE5jLTEpDQogICAgICAgICAgIDEvKE4uc3BMICsgTi5zcFMgLTIpIC0gMS8oMipOLnNwUyAtIDIpLCANCiAgICAgICAgIGxuVlIuZXMNCiAgICAgICAgICkNCiAgICAgIyBEaXZpZGUgdmFyaWFuY2UgYnkgNCBpbiBzcEwgd2hlcmVhcyBoeWJyaWRzIGFyZSBjb25zdGFudA0KICAgICApICU+JQ0KICAgbXV0YXRlX2F0KCJjcm9zcyIsIGFzLmZhY3RvcikgJT4lDQogICB3aXRoaW4obGV2ZWxzKGNyb3NzKSA8LSBjKCJoeWJMUyIsICJoeWJTTCIsICJtaWRwYXJlbnQiKSkNCg0KDQojKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrIw0KIyBDb21wYXJlIG1pZHBhcmVudCBhbmQgaHlicmlkcyBieSBtZXRhLXJlZ3Jlc3Nvbg0KIysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyMNCg0KZm9yICh0ciBpbiBjKCJBbGx0cmFpdHMiLCAiTm9ubm92ZWx0cmFpdHMiKSkgew0KICBmb3IgKHRheG9uIGluIGMoImFsbHRheG9uIiwgImluc2VjdCIpKSB7DQogICAgDQogICAgIyBGaWx0ZXJpbmcgdGF4b24gKGFsbCB0YXhvbiBvciBpbnNlY3RzKQ0KICAgIGlmICh0YXhvbiA9PSAiYWxsdGF4b24iKSB7DQogICAgICBkYXQgPC0gbWlkcGFyZW50ICU+JSANCiAgICAgICAgZmlsdGVyKGRhdGEudHlwZSA9PSB0cikNCiAgICB9IGVsc2Ugew0KICAgICAgZGF0IDwtIG1pZHBhcmVudCAlPiUgDQogICAgICAgIGZpbHRlcihkYXRhLnR5cGUgPT0gdHIsIGluc2VjdCA9PSB0YXhvbikNCiAgICB9DQoNCiAgICAjKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysjDQogICAgIyBFc3RpbWF0ZSBtZXRhLWFuYWx5dGljIG1lYW4gb2YgbWlkcGFyZW50IG9mIHBoZW5vdHlwaWMgdmFyaWF0aW9uDQogICAgIysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrIw0KICAgICMgbWlkcGFyZW50LmNvbXBhcmUgPC0gcm1hLm12KA0KICAgICMgICB5aSA9IGxuVlIubWlkcGFyZW50LmVzLCBWID0gbG5WUi5zdiwNCiAgICAjICAgZGF0YSA9IGRhdCwNCiAgICAjICAgbWV0aG9kID0gIlJFTUwiLA0KICAgICMgICByYW5kb20gPSBsaXN0KH4xIHwgc3BMLm5hbWUsIH4xIHwgU3R1ZHkuSUQsIH4xIHwgQ3Jvc3MuSUQsIH4xIHwgRVMuSUQpLA0KICAgICMgICBSID0gbGlzdChzcEwubmFtZSA9IHBoeWxvX2NvciksDQogICAgIyAgIG1vZHMgPSB+IHJlbGV2ZWwoY3Jvc3MsIHJlZiA9ICJtaWRwYXJlbnQiKQ0KICAgICMgICApDQogICAgIyAjIyBTYXZlIG1vZGVsICMjIw0KICAgICMgc2F2ZVJEUygNCiAgICAjICAgbWlkcGFyZW50LmNvbXBhcmUsDQogICAgIyAgIGZpbGUgPSBwYXN0ZSgiLi4vQW5hbHlzaXMvbG5WUi5taWRwYXJlbnQuY29tcGFyZSIsIHRyLCB0YXhvbiwgIm9iaiIsIHNlcCA9ICIuIikNCiAgICAjICAgKQ0KICANCiAgICBhc3NpZ24oDQogICAgICBwYXN0ZSgiRG9taW5hbmNlIiwgdHIsIHRheG9uLCBzZXAgPSAiLiIpLA0KICAgICAgcmVhZFJEUyhwYXN0ZSgiLi4vQW5hbHlzaXMvbG5WUi5taWRwYXJlbnQuY29tcGFyZSIsIHRyLCB0YXhvbiwgIm9iaiIsIHNlcCA9ICIuIikpICU+JSANCiAgICAgICAgZ2V0X3JlZygpICU+JQ0KICAgICAgICAjIFNob3cgZGF0YXNldCBuYW1lDQogICAgICAgIHdpdGhpbihEYXRhc2V0IDwtIGMocGFzdGUodHIsIHRheG9uKSwgcmVwKCIiLCBsZW5ndGgoLiRFc3RpbWF0ZSktMSkpKSAlPiUNCiAgICAgICAgIyBSZW5hbWUgZml4ZWQgZWZmZWN0cw0KICAgICAgICB3aXRoaW4oJ0ZpeGVkIGVmZmVjdHMnIDwtIGMoIiIsICJtaWRwYXJlbnQgKGludHJjcHQpIiwgImh5YkxTIiwgImh5YlNMIikpICU+JQ0KICAgICAgICAjIERpZmZlcmVuY2Ugb2YgZWFjaCBjcm9zcyBmcm9tIG1pZHBhcmVudCBpbiAlDQogICAgICAgIG11dGF0ZSgnQ29tcGFyaXNvbiB3aXRoIG1pZHBhcmVudCcgPSBjKA0KICAgICAgICAgIHJlcCgiIiwgMiksDQogICAgICAgICAgIyBEaWZmZXJlbmNlIGh5YkxTIC0gbWlkcGFyZW50DQogICAgICAgICAgcGFzdGUoDQogICAgICAgICAgICByb3VuZCgNCiAgICAgICAgICAgIDEwMCooZXhwKG1pZHBhcmVudC5jb21wYXJlJGJldGFbMV0rbWlkcGFyZW50LmNvbXBhcmUkYmV0YVsyXSkgICAgICAgICAgICAtZXhwKG1pZHBhcmVudC5jb21wYXJlJGJldGFbMV0pKSwgIyBoeWJyaWQgTFMNCiAgICAgICAgICAgIDIpLA0KICAgICAgICAgICAgIiUgbGFyZ2VyIg0KICAgICAgICAgICAgKSwNCiAgICAgICAgICAgICAgIyBiZXRhWzFdIDogbWlkcGFyZW50DQogICAgICAgICAgICAgICMgYmV0YVsyXSA6IGh5YkxTDQogICAgICAgICAgICAgICMgYmV0YVszXSA6IGh5YlNMDQogICAgICAgICAgIyBEaWZmZXJlbmNlIGh5YlNMIC0gbWlkcGFyZW50DQogICAgICAgICAgcGFzdGUoDQogICAgICAgICAgICByb3VuZCgNCiAgICAgICAgICAgIDEwMCooZXhwKG1pZHBhcmVudC5jb21wYXJlJGJldGFbMV0rbWlkcGFyZW50LmNvbXBhcmUkYmV0YVszXSktZXhwKG1pZHBhcmVudC5jb21wYXJlJGJldGFbMV0pKSwgIyBoeWJyaWQgU0wNCiAgICAgICAgICAgIDIpLA0KICAgICAgICAgICAgIiUgbGFyZ2VyIg0KICAgICAgICAgICAgKQ0KICAgICAgICAgICkpDQogICAgICApDQoNCiAgICAjKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyMNCiAgICAjIE1ldGEtYW5hbHlzaXMgZm9yIG1pZHBhcmVudCB0byBwbG90IGJhbmQNCiAgICAjKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyMNCiAgICAjIG1pZHBhcmVudC5yYW5kb20gPC0gcm1hLm12KA0KICAgICMgICB5aSA9IGxuVlIubWlkcGFyZW50LmVzLA0KICAgICMgICBWID0gbG5WUi5zdiwNCiAgICAjICAgZGF0YSA9IGRhdCAlPiUNCiAgICAjICAgICBmaWx0ZXIoY3Jvc3MgPT0gIm1pZHBhcmVudCIpLA0KICAgICMgICBtZXRob2QgPSAiUkVNTCIsDQogICAgIyAgIHJhbmRvbSA9IGxpc3QofjEgfCBzcEwubmFtZSwgfjEgfCBTdHVkeS5JRCwgfjEgfCBDcm9zcy5JRCwgfjEgfCBFUy5JRCksDQogICAgIyAgIFIgPSBsaXN0KHNwTC5uYW1lID0gcGh5bG9fY29yKQ0KICAgICMgICApDQogICAgIyAjIyBTYXZlIG1vZGVsICMjIw0KICAgICMgc2F2ZVJEUygNCiAgICAjICAgbWlkcGFyZW50LnJhbmRvbSwNCiAgICAjICAgZmlsZSA9IHBhc3RlKCIuLi9BbmFseXNpcy9sblZSLm1pZHBhcmVudCIsIHRyLCB0YXhvbiwgIm9iaiIsIHNlcCA9ICIuIikNCiAgICAjICAgKQ0KICAgIA0KICB9DQp9DQoNCmJpbmRfcm93cygNCiAgRG9taW5hbmNlLkFsbHRyYWl0cy5hbGx0YXhvbiwgRG9taW5hbmNlLk5vbm5vdmVsdHJhaXRzLmFsbHRheG9uLA0KICBEb21pbmFuY2UuQWxsdHJhaXRzLmluc2VjdCwgRG9taW5hbmNlLk5vbm5vdmVsdHJhaXRzLmluc2VjdA0KICApICU+JQ0KICBrYWJsZSgiaHRtbCIsIGRpZ2l0cyA9IDMsIGNhcHRpb24gPSAiTWV0YS1hbmFseXNlcyByZXN1bHRzIG9mIGZ1bGwgZGF0YXNldCBhbmQgZGF0YSBzdWJzZXRzIikgJT4lDQogIGthYmxlX3N0eWxpbmcoInN0cmlwZWQiLCBwb3NpdGlvbiA9ICJsZWZ0IikgJT4lDQogIHNjcm9sbF9ib3god2lkdGggPSAiMTAwJSIsIGhlaWdodCA9ICI1MDBweCIpDQoNCmBgYA0KDQoNCjxkaXYgc3R5bGU9Im1hcmdpbi1ib3R0b206NzBweDsiPg0KPC9kaXY+DQoNCiMjIENyb3NzaW5nIGRpcmVjdGlvbiBlZmZlY3QgaW4gcGhlbm90eXBpYyB2YXJpYWJpbGl0eSAgKGNvZWZmaWNpZW50IG9mIHZhcmlhdGlvbikNCg0KV2Ugc3RhdGlzdGljYWxseSBjb21wYXJlZCBsblZSIGZyb20gPGk+c3BTUzxzdWI+TTwvc3ViPjwvaT4gdG8gdGhlIG90aGVyIGNyb3NzZXMgdGhyb3VnaCB0aGUgZm9ybWFsIG1ldGEtcmVncmVzc2lvbiBieSB1c2luZyBgcm1hLm12YCBmdW5jdGlvbiBvZiBSIHBhY2thZ2UgYG1ldGFmb3JgLiA8YnI+IA0KSGVyZSB3ZSBhc2tlZCBpZiBsblZSIG9mIDxpPmh5YlNMPHN1Yj5WPC9zdWI+PC9pPiB3YXMgc21hbGxlci9sYXJnZXIgdGhhbiB0aGF0IG9mIDxpPmh5YkxTPHN1Yj5WPC9zdWI+PC9pPi4gU21hbGxlciBsblZSIG9mIDxpPmh5YlNMPHN1Yj5WPC9zdWI+PC9pPiBpbmRpY2F0ZXMgbWF0ZXJuYWwgaW5oZXJpdGFuY2UgaW4gcGhlbm90eXBpYyB2YXJpYWJpbGl0eSA8YnI+DQoNCmBgYHtyfQ0KDQpmb3IgKHRyIGluIGMoIkFsbHRyYWl0cyIsICJOb25ub3ZlbHRyYWl0cyIpKSB7DQoNCiAgaWYgKHRheG9uID09ICJhbGx0YXhvbiIpIHsNCiAgICBkYXQgPC0gTm92ZWwuTm9ubm92ZWwgJT4lIA0KICAgICAgZmlsdGVyKGRhdGEudHlwZSA9PSB0cikNCiAgfSBlbHNlIHsNCiAgICBkYXQgPC0gTm92ZWwuTm9ubm92ZWwgJT4lIA0KICAgICAgZmlsdGVyKGRhdGEudHlwZSA9PSB0ciwgaW5zZWN0ID09IHRheG9uKQ0KICB9DQogICAgDQogIGZvciAodGF4b24gaW4gYygiYWxsdGF4b24iLCAiaW5zZWN0IikpIHsNCiAgIysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysjDQogICMgcGh5bG9nZW5ldGljIHJhbmRvbSByZWdyZXNzb24gKEFOT1ZBKQ0KICAjKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyMNCiAgIyBwaHlsLnJhbmRvbS5oeWJMUyA8LSBybWEubXYoDQogICMgICB5aSA9IGxuVlIuZXMsIFYgPSBsblZSLnN2LA0KICAjICAgZGF0YSA9IGRhdCwgbWV0aG9kID0gIlJFTUwiLA0KICAjICAgcmFuZG9tID0gbGlzdCh+MSB8IHNwTC5uYW1lLCB+MSB8IFN0dWR5LklELCB+MSB8IENyb3NzLklELCB+MSB8IEVTLklEKSwNCiAgIyAgIFIgPSBsaXN0KHNwTC5uYW1lID0gcGh5bG9fY29yKSwNCiAgIyAgIG1vZHMgPSB+IGNyb3NzDQogICMgICApDQogICMgIyBTYXZlIG1vZGVsICMjIw0KICAjIHNhdmVSRFMoDQogICMgICBwaHlsLnJhbmRvbS5oeWJMUywNCiAgIyAgIGZpbGUgPSBwYXN0ZSgiLi4vQW5hbHlzaXMvbG5WUi5jb21wYXJlLmZyb20uaHliTFMiLCB0ciwgdGF4b24sICJvYmoiLCBzZXAgPSAiLiIpDQogICMgICApDQogICAgDQogICAgcGh5bC5yYW5kb20uaHliTFMgPC0gcmVhZFJEUygNCiAgICAgIHBhc3RlKCIuLi9BbmFseXNpcy9sblZSLmNvbXBhcmUuZnJvbS5oeWJMUyIsIHRyLCB0YXhvbiwgIm9iaiIsIHNlcCA9ICIuIikNCiAgICAgICkNCg0KICAgIGFzc2lnbigNCiAgICAgIHBhc3RlKCJSZWNpcHJvY2FsIiwgdHIsIHRheG9uLCBzZXAgPSAiLiIpLA0KICAgICAgcGh5bC5yYW5kb20uaHliTFMgJT4lIA0KICAgICAgICBnZXRfcmVnKCkgJT4lDQogICAgICAgICMgU2hvdyBkYXRhc2V0IG5hbWUNCiAgICAgICAgd2l0aGluKERhdGFzZXQgPC0gYyhwYXN0ZSh0ciwgdGF4b24pLCByZXAoIiIsIGxlbmd0aCguJEVzdGltYXRlKS0xKSkpICU+JQ0KICAgICAgICAjIFJlbmFtZSBmaXhlZCBlZmZlY3RzDQogICAgICAgIHdpdGhpbignRml4ZWQgZWZmZWN0cycgPC0gYygiIiwgImh5YkxTIChpbnRyY3B0KSIsICJoeWJTTCIsICJzcExMIikpICU+JQ0KICAgICAgICAjIERpZmZlcmVuY2Ugb2YgZWFjaCBjcm9zcyBmcm9tIG1pZHBhcmVudCBpbiAlDQogICAgICAgIG11dGF0ZSgnQ29tcGFyaXNvbiB3aXRoIGh5YnJpZExTJyA9IGMoDQogICAgICAgICAgcmVwKCIiLCAyKSwNCiAgICAgICAgICBwYXN0ZSgNCiAgICAgICAgICAgIHJvdW5kKA0KICAgICAgICAgICAgICAoZXhwKHBoeWwucmFuZG9tLmh5YkxTJGJldGFbMV0rcGh5bC5yYW5kb20uaHliTFMkYmV0YVsyXSkgLQ0KICAgICAgICAgICAgICAgICBleHAocGh5bC5yYW5kb20uaHliTFMkYmV0YVsxXSkNCiAgICAgICAgICAgICAgICkqMTAwLA0KICAgICAgICAgICAgICAyKSwNCiAgICAgICAgICAgICIlIGxhcmdlciINCiAgICAgICAgICAgICksIA0KICAgICAgICAgICIiDQogICAgICAgICAgKQ0KICAgICAgICApDQogICAgICApDQogIH0NCn0NCg0KYmluZF9yb3dzKA0KICBSZWNpcHJvY2FsLkFsbHRyYWl0cy5hbGx0YXhvbiwgUmVjaXByb2NhbC5Ob25ub3ZlbHRyYWl0cy5hbGx0YXhvbiwNCiAgUmVjaXByb2NhbC5BbGx0cmFpdHMuaW5zZWN0LCBSZWNpcHJvY2FsLk5vbm5vdmVsdHJhaXRzLmluc2VjdA0KICApICU+JQ0KICBrYWJsZSgiaHRtbCIsIGRpZ2l0cyA9IDMsIGNhcHRpb24gPSAiTWV0YS1hbmFseXNlcyByZXN1bHRzIG9mIGZ1bGwgZGF0YXNldCBhbmQgZGF0YSBzdWJzZXRzIikgJT4lIA0KICBrYWJsZV9zdHlsaW5nKCJzdHJpcGVkIiwgcG9zaXRpb24gPSAibGVmdCIpICU+JQ0KICBzY3JvbGxfYm94KHdpZHRoID0gIjEwMCUiLCBoZWlnaHQgPSAiNTAwcHgiKQ0KDQpgYGANCg0KDQoNCjxkaXYgc3R5bGU9Im1hcmdpbi1ib3R0b206MTgwcHg7Ij4NCjwvZGl2Pg0KIyBTZXNzaW9uIGluZm9ybWF0aW9uDQpgYGB7cn0NCnNlc3Npb25JbmZvKCkgICMgc2hvdyBSIHZlcnNpb24gZXRjDQpgYGANCg0KPGRpdiBzdHlsZT0ibWFyZ2luLWJvdHRvbToxMjBweDsiPg0KPC9kaXY+DQoNCiMgUmVmZXJlbmNlcw0KDQo=